public function SearchApiSolrBackend::search in Search API Solr 8
Same name and namespace in other branches
- 8.3 src/Plugin/search_api/backend/SearchApiSolrBackend.php \Drupal\search_api_solr\Plugin\search_api\backend\SearchApiSolrBackend::search()
- 8.2 src/Plugin/search_api/backend/SearchApiSolrBackend.php \Drupal\search_api_solr\Plugin\search_api\backend\SearchApiSolrBackend::search()
- 4.x src/Plugin/search_api/backend/SearchApiSolrBackend.php \Drupal\search_api_solr\Plugin\search_api\backend\SearchApiSolrBackend::search()
Options on $query prefixed by 'solr_param_' will be passed natively to Solr as query parameter without the prefix. For example you can set the "Minimum Should Match" parameter 'mm' to '75%' like this:
$query
->setOption('solr_param_mm', '75%');
Overrides BackendSpecificInterface::search
File
- src/
Plugin/ search_api/ backend/ SearchApiSolrBackend.php, line 884
Class
- SearchApiSolrBackend
- Apache Solr backend for search api.
Namespace
Drupal\search_api_solr\Plugin\search_api\backendCode
public function search(QueryInterface $query) {
$mlt_options = $query
->getOption('search_api_mlt');
if (!empty($mlt_options)) {
$query
->addTag('mlt');
}
// Call an object oriented equivalent to hook_search_api_query_alter().
$this
->alterSearchApiQuery($query);
// Get field information.
/** @var \Drupal\search_api\Entity\Index $index */
$index = $query
->getIndex();
$index_id = $this
->getIndexId($index
->id());
$field_names = $this
->getSolrFieldNames($index);
$connector = $this
->getSolrConnector();
$solarium_query = NULL;
$index_fields = $index
->getFields();
$index_fields += $this
->getSpecialFields($index);
if ($query
->hasTag('mlt')) {
$solarium_query = $this
->getMoreLikeThisQuery($query, $index_id, $index_fields, $field_names);
}
else {
// Instantiate a Solarium select query.
$solarium_query = $connector
->getSelectQuery();
// Extract keys.
$keys = $query
->getKeys();
if (is_array($keys)) {
$keys = $this
->flattenKeys($keys);
}
if (!empty($keys)) {
// Set them.
$solarium_query
->setQuery($keys);
}
// Set searched fields.
$search_fields = $this
->getQueryFulltextFields($query);
$query_fields = [];
$query_fields_boosted = [];
foreach ($search_fields as $search_field) {
$query_fields[] = $field_names[$search_field];
/** @var \Drupal\search_api\Item\FieldInterface $field */
$field = $index_fields[$search_field];
$boost = $field
->getBoost() ? '^' . $field
->getBoost() : '';
$query_fields_boosted[] = $field_names[$search_field] . $boost;
}
$solarium_query
->getEDisMax()
->setQueryFields(implode(' ', $query_fields_boosted));
// Set highlighting and excerpt.
$this
->setHighlighting($solarium_query, $query, $query_fields);
}
$options = $query
->getOptions();
// Set basic filters.
$filter_queries = $this
->getFilterQueries($query, $field_names, $index_fields, $options);
foreach ($filter_queries as $id => $filter_query) {
$solarium_query
->createFilterQuery('filters_' . $id)
->setQuery($filter_query['query'])
->addTags($filter_query['tags']);
}
$query_helper = $connector
->getQueryHelper($solarium_query);
// Set the Index filter.
$solarium_query
->createFilterQuery('index_id')
->setQuery('index_id:' . $query_helper
->escapePhrase($index_id));
// Set the site hash filter, if enabled.
if ($this->configuration['site_hash']) {
$site_hash = $query_helper
->escapePhrase(SearchApiSolrUtility::getSiteHash());
$solarium_query
->createFilterQuery('site_hash')
->setQuery('hash:' . $site_hash);
}
// @todo Make this more configurable so that Search API can choose which
// fields it wants to fetch. But don't skip the minimum required fields as
// currently set in the "else" path.
// @see https://www.drupal.org/node/2880674
if (!empty($this->configuration['retrieve_data'])) {
$solarium_query
->setFields([
'*',
'score',
]);
}
else {
$returned_fields = [
$field_names['search_api_id'],
$field_names['search_api_language'],
$field_names['search_api_relevance'],
];
if (!$this->configuration['site_hash']) {
$returned_fields[] = 'hash';
}
$solarium_query
->setFields($returned_fields);
}
// Set sorts.
$this
->setSorts($solarium_query, $query, $field_names);
// Set facet fields. setSpatial() might add more facets.
$this
->setFacets($query, $solarium_query, $field_names);
// Handle spatial filters.
if (isset($options['search_api_location'])) {
$this
->setSpatial($solarium_query, $options['search_api_location'], $field_names);
}
// Handle spatial filters.
if (isset($options['search_api_rpt'])) {
if (version_compare($connector
->getSolrVersion(), 5.1, '>=')) {
$this
->setRpt($solarium_query, $options['search_api_rpt'], $field_names);
}
else {
\Drupal::logger('search_api_solr')
->error('Rpt data type feature is only supported by Solr version 5.1 or higher.');
}
}
// Handle field collapsing / grouping.
$grouping_options = $query
->getOption('search_api_grouping');
if (!empty($grouping_options['use_grouping'])) {
$this
->setGrouping($solarium_query, $query, $grouping_options, $index_fields, $field_names);
}
if (isset($options['offset'])) {
$solarium_query
->setStart($options['offset']);
}
$rows = isset($options['limit']) ? $options['limit'] : 1000000;
$solarium_query
->setRows($rows);
if (!empty($options['search_api_spellcheck'])) {
$solarium_query
->getSpellcheck();
}
foreach ($options as $option => $value) {
if (strpos($option, 'solr_param_') === 0) {
$solarium_query
->addParam(substr($option, 11), $value);
}
}
$this
->applySearchWorkarounds($solarium_query, $query);
try {
// Allow modules to alter the solarium query.
$this->moduleHandler
->alter('search_api_solr_query', $solarium_query, $query);
$this
->preQuery($solarium_query, $query);
// Send search request.
$response = $connector
->search($solarium_query);
$body = $response
->getBody();
if (200 != $response
->getStatusCode()) {
throw new SearchApiSolrException(strip_tags($body), $response
->getStatusCode());
}
$this
->alterSolrResponseBody($body, $query);
$response = new Response($body, $response
->getHeaders());
$result = $connector
->createSearchResult($solarium_query, $response);
// Extract results.
$results = $this
->extractResults($query, $result);
// Add warnings, if present.
if (!empty($warnings)) {
foreach ($warnings as $warning) {
$results
->addWarning($warning);
}
}
// Extract facets.
if ($result instanceof Result) {
if ($facets = $this
->extractFacets($query, $result, $field_names)) {
$results
->setExtraData('search_api_facets', $facets);
}
}
$this->moduleHandler
->alter('search_api_solr_search_results', $results, $query, $result);
$this
->postQuery($results, $query, $result);
} catch (\Exception $e) {
throw new SearchApiSolrException($this
->t('An error occurred while trying to search with Solr: @msg.', array(
'@msg' => $e
->getMessage(),
)), $e
->getCode(), $e);
}
}