How do I make a custom entity update or create automatically update the solr index? I have implemented a custom entity type which is essentially identical to what the Model module does, with a few additional fields.

I have followed the Apachesolr User module to understand how to index my custom entities in the solr index. But when I add, or update and existing, entity the solr index is not automatically picking up the changes.

/**
 * Implements hook_apacheolr_entity_info_alter().
 */
function my_entity_apachesolr_entity_info_alter(&amp;$entity_info) {
  $entity_info['my_entity']['indexable'] = TRUE;
  $entity_info['my_entity']['status callback'][] = 'my_entity_status_callback';
  $entity_info['my_entity']['document callback'][] = 'my_entity_solr_document';
  $entity_info['my_entity']['reindex callback'] = 'my_entity_solr_reindex';
  $entity_info['my_entity']['index_table'] = 'apachesolr_index_entities_my_entity';

  $entity_info['my_entity']['result callback'] = 'my_entity_result';
}


This is the hook I had to implement to index my content, the various callbacks are irrelevant. It is worth noting the index table needs to be implemented in hook_schema() as well. This can be easily seen in Apachesolr User
Originally I thought I had to implement my own hooks but after seeing that apachesolr took care of deletes I wondered why it hadn't taken care of my updates and inserts.

There is actually a apachesolr_entity_update/insert() which calls apachesolr_entity_should_index(). That checks whether your entity info (returned by entity_get_info($entity_type)) has the following key set:

$info['bundles'][$bundle]['apachesolr']['index']


Where $bundle is the $entity bundle. This made it pretty easy for me to figure out that I just had to add some stuff to my hook_entity_info_alter():

function my_entity_entity_info_alter(&amp;$entity_info) {
  foreach (my_entity_get_types() as $type =&gt; $info) {
    $entity_info['my_entity']['bundles'][$type] = array(
      'apachesolr' =&gt; array('index' =&gt; TRUE),
    );
  }
}


After adding that and clearing cache I no longer needed my entity update/insert hooks.

Note: Don't get this confused with hook_apachesolr_entity_info_alter like I did!

Original Answer

I found the function apachesolr_index_get_entities_to_index() which checks the indexer table for your entity_type for a changed timestamp that's greater than what it's last seen (I have yet to find out where it sets that). Essentially we just need to automate the updating of that table. This can be done with 2 hooks:

hook_entity_insert()
hook_entity_update()

/**
 * Implements hook_entity_insert().
 */
function my_entity_entity_insert($entity, $type) {
  // Update our indexer table
  if ($type != 'my_entity') {
    return;
  }
  $indexer_table = apachesolr_get_indexer_table($type);

 // Insert the new entity into a fictional table of all entities.
  $info = entity_get_info($type);
  list($id) = entity_extract_ids($type, $entity);
  db_insert($indexer_table)-&gt;fields(array(
    'entity_type' =&gt; $type,
    'bundle' =&gt; $entity-&gt;type,
    'entity_id' =&gt; $id,
    'changed' =&gt; REQUEST_TIME,
  ))-&gt;execute();
}

/**
 * Implements hook_entity_update().
 */
function my_entity_entity_update($entity, $type) {
  // Update our indexer table
  if ($type != 'my_entity') {
    return;
  }
  $indexer_table = apachesolr_get_indexer_table($type);

  db_update($indexer_table)
    -&gt;fields(array(
      'changed' =&gt; REQUEST_TIME,
    ))
  -&gt;condition('entity_id', $entity-&gt;entity_id)
  -&gt;execute();
}


You may have to add this line into the insert statement in hook_entity_insert() if you have a status coming from $entity (mine is always 1 so the db table defaults it to that).

'status' =&gt; $entity-&gt;status,


Edit: You may be wondering "What about delete??", this seems to be taken care of by  apachesolr_entity_delete, I'm going to see why  apachesolr_entity_update and  apachesolr_entity_insert didn't take care of my entities. However this answer is still valid.