Adding Custom Fields to Apache Solr Search Results

As I mentioned in my previous post on adding a custom sort to Solr, this post is about something that is even simpler; adding a new field to the search results.  In our particular use case, we wanted to add a CCK image field to the results.  To add a slight twist, we needed to add a different image depending on the content type: the user picture for a profile node (created with content_profile module) or a CCK imagefield named field_main_image from the other content types.

To do this, we will use the two hooks used in the last example: hook_apachesolr_update_index() and hook_apachesolr_modify_query().  To start, we need to add the data to the Solr index.

/**
 * Implementation of hook_apachesolr_update_index()
 */
function mymodule_apachesolr_update_index(&$document, $node) {
  // Index field_main_image as a separate field
  if ($node->type == 'profile') {
    $user = user_load(array('uid' => $node->uid));
    $document->setMultiValue('sm_field_main_image', $user->picture);
  }
  elseif (count($node->field_main_image)) {
    foreach ($node->field_main_image AS $image) {
      $document->setMultiValue('sm_field_main_image', $image['filepath']);
    }
  }
}


All we do is add the data to the index by adding it to the $doument object, which is passed by reference.  We are using the setMultiValue method since the imagefield can have multiple values, but if we were just adding one field, we would just use the addField method.  And, actually, according to the comments in the setMultiValue method, it is deprecated in favor of using addField, but this is working fine right now.  The field name is simply the 'sm_' dynamic field name pattern with field_main_image appended, since the field contains a string of the path to the image, and the sm_ field type represents a medium string (as defined in schema.xml).

Now that the data has been added to the index, we also need to add it to the query so it can be returned in the search results.  This is done amazingly easily:

function mymodule_apachesolr_modify_query(&$query, &$params, $caller) {
  $params['fl'] .= ',sm_field_main_image';
}


Without going into too much detail on the format of $params, all you're doing is some basic PHP string concatenation and appending your newly indexed field to the fields to return array (['fl'])of the $params object.  For more information on $params, see the DCSF session video starting at 37:30.

And that's all there is to it; two very small hook implementations. Pretty easy, and pretty powerful.  Now that we have that down, we can do even more complex stuff.  My next post on Solr will be a slightly more involved example of creating a custom search path.

Thanks for the great tip!

Thanks for the great tip!

Thanks for the tip and the

Thanks for the tip and the clean code.

Thanks for the good

Thanks for the good instructions! However, even though my custom field gets indexed correctly it is not shown in the search results. I have confirmed that both hooks get called. The indexing works cause I was able to create facet and I can filter based on my custom field but it's just not showing up in the search results.

Any idea what I need to do in order to get my custom field show up in the search results?

where you able to find why

where you able to find why the new cck field didnt show up? i have same issue. Any hint ?

thank you for the quick

thank you for the quick introducion to the drupal solr update_index.

it is deprecated in favor of

it is deprecated in favor of using addField

Don't you mean setField()?

Everybody talks about website

Everybody talks about website designs. that can dynamically change to adapt to a viewer's personality type. Perhaps the viewer nanswers 2 or 3 questions and the site displays a redesigned view..this post is about something that is even simpler; adding a new field to the search results. In our particular use case, we wanted to add a CCK image field to the results. To add a slight twist, we needed to add a different image depending on the content.

Thanks. I'm going to be using

Thanks. I'm going to be using this function quite often.

kind regards
Submit Link

I added the 2 hooks, I can

I added the 2 hooks, I can see my new cck image file being indexed. But my search result is not showing the newly added field. I don't see any code in search-results.tpl.php or search-result.tpl.php to pull from newly added params. Iam not sure what is missing. Any suggestions??

This should help with

This should help with displaying you newly added fields on your search results page http://drupal.org/node/955894. Specifically with Steop 2 of 2

Nice concise post on a

Nice concise post on a specific capability of drupal solr.
I am evaluating solr and have a 3-part question.
Is Drupal solr capable of indexing and searching multiple custom content types (created w/ CCK for a single site) ?
Are there any special steps required in building the front-end interface (normal search box) to accomodate multiple custom content types?
Any foreseeable challenges to implementing this?
If anyone feels like offering tips or directing me to a link that could help, I would be very grateful!
~

awesome tutorial i like the

awesome tutorial i like the "hooks" part most,i love the way you illustrated the above scripts they are very useful and helpful

Very nice the tutorial,thank

Very nice the tutorial,thank you for the script,great blog men.

Awesome tutorial, thanks a

Awesome tutorial, thanks a lot for sharing!

Hi, I have tried this

Hi, I have tried this implementation and though _apachesolr_modify_query is being called correctly, _apachesolr_update_index is not. Hence I'm unable to include any additional fields.

Any help with this will be deeply appreciated.

Thanks in advance.

Is it possible to get fields

Is it possible to get fields from the Apache Solr Biblio module with the apachesolr_modify_query hook? Do we still need to update the index?

I would say that you have to

I would say that you have to do the merging inside your override function, since if we merge from inside hook_apachesolr_modify_query() then there'd be no way for implemented hooks to remove default filters (or those implemented by other hook implementations).

You may often have content in

You may often have content in Drupal that should not appear for certain user roles. There are many ways to accomplish this in the CMS, but restricting them from search results is often overlooked. If you are using Apache Solr for your search engine, the apachesolr_nodeaccess module integrates with Drupal’s node access system to restrict results. However, what if your access rules are more fine-grained than just content types?

You could return all results

You could return all results and use logic in your template to determine if a result should be shown to a user, but it’s much more efficient to use the apachesolr module’s hooks to determine what search results are returned.

The first parameter to the

The first parameter to the add_filter function is the field name, the second is the value to search on, and the third is a boolean value. If this value is true, then matching items are removed from the result set. You can add filters on any of the fields that are in the index such as node type or status, not just ones that you have created.

hi. is it good code for d7?

hi. is it good code for d7?

how we can sort the nodes

how we can sort the nodes based on some cck field without showing that cck field under sort option on front-end?

See my other post on creating

See my other post on creating sorts.  I talk about the difference between the prepare_query and modify_query hooks, and what is shown on the screen depending on which hook is used.

Post new comment

The content of this field is kept private and will not be shown publicly.
  • Web page addresses and e-mail addresses turn into links automatically.
  • Allowed HTML tags: <a> <em> <strong> <cite> <code> <ul> <ol> <li> <dl> <dt> <dd><img>
  • Lines and paragraphs break automatically.

More information about formatting options

By submitting this form, you accept the Mollom privacy policy.