Skip to main content
Drupal 7 SOLR

Drupal 7 filtering SOLR results

Search plays a crucial role in content driven websites. Drupal and the Open source enterprise search platform Solr form a effective combination. Drupal 7 has apachesolr module which  integrates Drupal with the Apache Solr search platform. I am going to detail on how to alter the solr query to get better and precise results.

Use cases:
  1. You may limit the result set to specific content types
  2. Search only on specific fields
  3. Modify the field weightage
  4. Restrict results based on conditions
and so on.
 
Hook used:
 
We need to use hook_apachesolr_query_prepare($query) hook to add custom params. 
 
Limiting results set:
 
Lets write a simple query, to limit results to two content types,
 

function MODULE_search_apachesolr_query_prepare($query) {

  $compiled_filter = new SolrFilterSubQuery('OR');

  $compiled_filter->addFilter('bundle''student');

  $compiled_filter->addFilter('bundle''teacher');

  $query->addFilterSubQuery($compiled_filter);

}

 
Searching specific fields:
 
To search only on specific fields,
 
$query->addParam('qf','label')
 
The above param makes solr to search only in label field. 
 
$query->addParam('qf','label content')
 
The above param makes solr to search only in label and content fields. 
 
 
Field weightage
 
$query->addParam('qf','content^3 label^5')
 
the above code specifies field weighatge. Meaning label has higher precedence than content. Label is the node title here.
 
Nesting Filters:
 
Lets assume you have validity field, based on it, you want to receive only valid records leaving old dated records.
 

  $filter2 = new SolrFilterSubQuery('AND');

  $filter2->addFilter('bundle''student');

  $filter2->addFilter('dm_field_student_validity','[NOW TO *]');

 

It receives the students who have validity date not lesser than current date. You can nest multiple filters,

 

function MODULE_apachesolr_query_prepare($query) {

  $filter = new SolrFilterSubQuery('AND');

  $filter->addFilter('bundle''student');

  $filter->addFilter('dm_field_student_validity','[NOW TO *]');

 

 

  $compiled_filter = new SolrFilterSubQuery('OR');

  $compiled_filter->addFilter('bundle''teacher');

  $compiled_filter->addFilterSubQuery($filter);

 

  //finally add the compiled filter to main query object

  $query->addFilterSubQuery($compiled_filter);

}

 

Comments

Nick_vh (not verified)

Mon, 01/07/2013 - 04:33

I think you mean hook_apachesolr_query_prepare

And, depending on the use-case, it might be more straight-forward to do hook_apachesolr_query_alter(), there is not really a big difference aside from the fact that query_prepare executes in static cached situations (with little or no effect I must add) and that it will add the start param to the query. Also it will add the defType if that is defined but that is a rare use case.

If you want to see the possibilities of the queries and subqueries, I suggest you take a look at the solr_base_query.test and solr_base_subquery.test files, loads of examples there :-)