If the default behavior of the apachesolr module doesn't cut it for you, you might want to perform some custom queries or add some custom fields to the index.
Basic queries:
<?php $query = apachesolr_drupal_query('apachesolr'); $query->addFilter('bundle', 'article') ->addParam('rows', '100') ->addParam('start', '200') ->addParam('fl', 'entity_id'); // use the 'fl' param to restrict fields that are returned // add a set of OR filters $subfilterkeywords = array('subfilter1', 'subfilter2'); $subquery = apachesolr_drupal_query('apachesolr'); foreach ($subfilterkeywords as $subfilterkeyword) { $subsubquery = apachesolr_drupal_query('apachesolr'); $subsubquery->addFilter('tm_field_some_custom_field', $subfilterkeyword); $subquery->addFilterSubQuery($subsubquery, 'OR'); } $query->addFilterSubQuery($subquery); $keywords = "keyword1 keyword2"; $response = $query->search($keywords); ?>
To add a custom field to the Solr index:
* note: String (ss_ and sm_) stores a word/sentence as an exact string without performing tokenization etc. Commonly useful for storing exact matches, e.g, for facetting.
Text (ts_ and tm_) typically performs tokenization, and secondary processing (such as lower-casing etc.). Useful for all scenarios when we want to match part of a sentence.
<?php /** * Implements hook_apachesolr_index_document_build_ENTITY_TYPE() */ mymodule_apachesolr_index_document_build_node(ApacheSolrDocument $document, $entity, $entity_type){ $lang = isset($entity->language) ? $entity->language : 'und'; $my_custom_field = isset($entity->field_my_custom_field[$lang][0]['safe_value']) ? $entity->field_my_custom_field[$lang][0]['safe_value'] : FALSE; if ($my_custom_field) { $document->addField('ss_field_my_custom_field', $my_custom_field); } } ?>
The methods below are good for inspecting the query in, for example, hook_apachesolr_query_alter or hook_apachesolr_query_prepare.
<?php sdpm($this->query); dpm($this->query->getContext()); dpm($this->query->getFilters()); dpm($this->query->getParams()); dpm($this->query->getPath()); dpm($this->query->getSolrParams()); ?>
Finally, here is a class that sums it all up, including the ability to get the 'page' and 'solrsort' GET query parameter and use it to display a particular page of results sorted by a custom field:
<?php /** * @file MyModuleQuery.php */ /** * Perform solr queries * $query = new MyModuleQuery(); * $query->addFilter('bundle', 'article'); * $response = $query->doQuery(); * @see apachesolr_drupal_query() */ class MyModuleQuery { private $query; private $solrsort; private $sortdirection; private $page; public function __construct() { $this->query = apachesolr_drupal_query('apachesolr'); $this->query_params = drupal_get_query_parameters(); $this->query->paperParams = array(); $this->solrsort = isset($this->query_params['solrsort']) ? $this->query_params['solrsort'] : 'ds_search_date'; $this->sortdirection = isset($this->query_params['sortdirection']) ? $this->query_params['sortdirection'] : 'desc'; $this->page = isset($this->query_params['page']) ? $this->query_params['page'] : '1'; $this->rows = '10'; } /** * Add a solr parameter * @see apachesolr_drupal_query() */ public function addParam($key, $value) { $this->query->addParam($key, $value); return $this; } /** * Add a solr filter * @see apachesolr_drupal_query() */ public function addFilter($key, $value) { $this->query->addFilter($key, $value); return $this; } /** * Add a solr sort * @see apachesolr_drupal_query() */ public function setSolrsort($sort, $direction = 'desc'){ $this->solrsort = $sort; $this->sortdirection = $direction; } /** * Set number of rows to return * @see apachesolr_drupal_query() */ public function setRows($rows){ $this->rows = $rows; } /** * Set some common parameters: * - sort field and direction * - start param * @see apachesolr_drupal_query() */ protected function processRequest() { $this->addParam('sort', "$this->solrsort $this->sortdirection"); $this->addParam('start', ($this->page -1) * $this->rows); } /** * Process the query and return the result * @see apachesolr_do_query() */ public function doQuery() { $this->processRequest(); return $this->query->search(); } }