Executing a search in code

Last updated on
21 April 2024

The following shows how to execute a Search API search programmatically, with some example code:

$index = \Drupal\search_api\Entity\Index::load('INDEX_ID');
$query = $index->query();

// Change the parse mode for the search.
$parse_mode = \Drupal::service('plugin.manager.search_api.parse_mode')
  ->createInstance('direct');
$parse_mode->setConjunction('OR');
$query->setParseMode($parse_mode);

// Set fulltext search keywords and fields.
$query->keys('alea iacta');
$query->setFulltextFields(['title', 'name', 'body']);

// Set additional conditions.
$query->addCondition('status', 1)
  ->addCondition('author', 1, '<>');

// Add more complex conditions.
// (In this case, a condition for a specific datasource).
$time = \Drupal::service('datetime.time')->getRequestTime();
$conditions = $query->createConditionGroup('OR');
$conditions->addCondition('search_api_datasource', 'entity:node', '<>')
  ->addCondition('created', $time - 7 * 24 * 3600, '>=');
$query->addConditionGroup($conditions);

// Restrict the search to specific languages.
$query->setLanguages(['de', 'it']);

// Do paging.
$query->range(20, 10);

// Add sorting.
$query->sort('search_api_relevance', 'DESC');

// Set additional options.
// (In this case, retrieve facets, if supported by the backend.)
$server = $index->getServerInstance();
if ($server->supportsFeature('search_api_facets')) {
  $query->setOption('search_api_facets', [
    'type' => [
      'field' => 'type',
      'limit' => 20,
      'operator' => 'and',
      'min_count' => 1,
      'missing' => TRUE,
    ],
  ]);
}

// Set one or more tags for the query.
// @see hook_search_api_query_TAG_alter()
// @see hook_search_api_results_TAG_alter()
$query->addTag('custom_search');

// Execute the search.
$results = $query->execute();

echo "Result count: {$results->getResultCount()}\n";
$ids = implode(', ', array_keys($results->getResultItems()));
echo "Returned IDs: $ids.\n";
$facets = $results->getExtraData('search_api_facets', []);
echo 'Facets data: ' . var_export($facets, TRUE);

For more information about available methods and functionality, see the interfaces in the \Drupal\search_api\Query namespace.

Use QueryInterface::setSearchId() to set an ID for the search, linking it to the search display plugin of the same ID (if there is any). This enables further functionality to be added to the search by other modules, like Facets.

Furthermore, the search_api.query_helper service can be used to retrieve other searches executed previously in this page request.

Another way to get content out of the results is something like this, where 'rendered_item' is the machine name of a field in the SAPI config (other common ones would be 'title'):

$output = '';
foreach ($results->getResultItems() as $result) {
  $value = $result->getField('rendered_item')->getValues();
  $output .= $value[0];
}

Note:

If you have the index saved on Apache SOLR or Elastic search, you might need to retrieve data directly from indexed server, otherwise the above code will fetch the resultset from Drupal DB.

For Apache SOLR, you need to enable "Retrieve result data from Solr" checkbox under Advanced settings in Search Server settings page.

Apache SOLR retrieve results

Help improve this page

Page status: No known problems

You can: