protected function SearchApiSolrBackend::extractResults in Search API Solr 8.3
Same name and namespace in other branches
- 8 src/Plugin/search_api/backend/SearchApiSolrBackend.php \Drupal\search_api_solr\Plugin\search_api\backend\SearchApiSolrBackend::extractResults()
- 8.2 src/Plugin/search_api/backend/SearchApiSolrBackend.php \Drupal\search_api_solr\Plugin\search_api\backend\SearchApiSolrBackend::extractResults()
- 4.x src/Plugin/search_api/backend/SearchApiSolrBackend.php \Drupal\search_api_solr\Plugin\search_api\backend\SearchApiSolrBackend::extractResults()
Extract results from a Solr response.
Parameters
\Drupal\search_api\Query\QueryInterface $query: The Search API query object.
\Solarium\Core\Query\Result\ResultInterface $result: A Solarium select response object.
Return value
\Drupal\search_api\Query\ResultSetInterface A result set object.
Throws
\Drupal\search_api\SearchApiException
1 call to SearchApiSolrBackend::extractResults()
- SearchApiSolrBackend::search in src/
Plugin/ search_api/ backend/ SearchApiSolrBackend.php - 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:
File
- src/
Plugin/ search_api/ backend/ SearchApiSolrBackend.php, line 2437
Class
- SearchApiSolrBackend
- Apache Solr backend for search api.
Namespace
Drupal\search_api_solr\Plugin\search_api\backendCode
protected function extractResults(QueryInterface $query, ResultInterface $result) {
$index = $query
->getIndex();
$fields = $index
->getFields(TRUE);
$site_hash = $this
->getTargetedSiteHash($index);
// We can find the item ID and the score in the special 'search_api_*'
// properties. Mappings are provided for these properties in
// SearchApiSolrBackend::getSolrFieldNames().
$language_unspecific_field_names = $this
->getSolrFieldNames($index);
$id_field = $language_unspecific_field_names['search_api_id'];
$score_field = $language_unspecific_field_names['search_api_relevance'];
$language_field = $language_unspecific_field_names['search_api_language'];
// Set up the results array.
$result_set = $query
->getResults();
$result_set
->setExtraData('search_api_solr_response', $result
->getData());
// In some rare cases (e.g., MLT query with nonexistent ID) the response
// will be NULL.
$is_grouping = $result instanceof Result && $result
->getGrouping();
if (!$result
->getResponse() && !$is_grouping) {
$result_set
->setResultCount(0);
return $result_set;
}
// If field collapsing has been enabled for this query, we need to process
// the results differently.
$grouping = $query
->getOption('search_api_grouping');
if (!empty($grouping['use_grouping'])) {
$docs = [];
$resultCount = 0;
if ($result_set
->hasExtraData('search_api_solr_response')) {
$response = $result_set
->getExtraData('search_api_solr_response');
foreach ($grouping['fields'] as $field) {
// @todo handle languages
$solr_field_name = $language_unspecific_field_names[$field];
if (!empty($response['grouped'][$solr_field_name])) {
$resultCount = count($response['grouped'][$solr_field_name]);
foreach ($response['grouped'][$solr_field_name]['groups'] as $group) {
foreach ($group['doclist']['docs'] as $doc) {
$docs[] = $doc;
}
}
}
}
// Set a default number then get the groups number if possible.
$result_set
->setResultCount($resultCount);
if (count($grouping['fields']) == 1) {
$field = reset($grouping['fields']);
// @todo handle languages
$solr_field_name = $language_unspecific_field_names[$field];
if (isset($response['grouped'][$solr_field_name]['ngroups'])) {
$result_set
->setResultCount($response['grouped'][$solr_field_name]['ngroups']);
}
}
}
}
else {
$result_set
->setResultCount($result
->getNumFound());
$docs = $result
->getDocuments();
}
// Add each search result to the results array.
/** @var \Solarium\QueryType\Select\Result\Document $doc */
foreach ($docs as $doc) {
if (is_array($doc)) {
$doc_fields = $doc;
}
else {
/** @var \Solarium\QueryType\Select\Result\Document $doc */
$doc_fields = $doc
->getFields();
}
if (empty($doc_fields[$id_field])) {
throw new SearchApiSolrException(sprintf('The result does not contain the essential ID field "%s".', $id_field));
}
$item_id = $doc_fields[$id_field];
// For items coming from a different site, we need to adapt the item ID.
if (isset($doc_fields['hash']) && !$this->configuration['site_hash'] && $doc_fields['hash'] != $site_hash) {
$item_id = $doc_fields['hash'] . '--' . $item_id;
}
$result_item = NULL;
if (Utility::hasIndexJustSolrDatasources($index)) {
$datasource = '';
if ($index
->isValidDatasource('solr_document')) {
$datasource = 'solr_document';
}
elseif ($index
->isValidDatasource('solr_multisite_document')) {
$datasource = 'solr_multisite_document';
}
/** @var \Drupal\search_api_solr\SolrDocumentFactoryInterface $solr_document_factory */
$solr_document_factory = \Drupal::getContainer()
->get($datasource . '.factory');
$result_item = $this->fieldsHelper
->createItem($index, $datasource . '/' . $item_id);
// Create the typed data object for the Item immediately after the query
// has been run. Doing this now can prevent the Search API from having
// to query for individual documents later.
$result_item
->setOriginalObject($solr_document_factory
->create($result_item));
}
else {
$result_item = $this->fieldsHelper
->createItem($index, $item_id);
}
if ($language_field && isset($doc_fields[$language_field])) {
$language_id = $doc_fields[$language_field];
$result_item
->setLanguage($language_id);
$field_names = $this
->getLanguageSpecificSolrFieldNames($language_id, $index);
}
else {
$field_names = $language_unspecific_field_names;
}
$result_item
->setExtraData('search_api_solr_document', $doc);
if (isset($doc_fields[$score_field])) {
$result_item
->setScore($doc_fields[$score_field]);
unset($doc_fields[$score_field]);
}
// The language field should not be removed. We keep it in the values as
// well for backward compatibility and for easy access.
unset($doc_fields[$id_field]);
// Extract properties from the Solr document, translating from Solr to
// Search API property names. This reverses the mapping in
// SearchApiSolrBackend::getSolrFieldNames().
foreach ($field_names as $search_api_property => $solr_property) {
if (isset($doc_fields[$solr_property]) && isset($fields[$search_api_property])) {
$doc_field = is_array($doc_fields[$solr_property]) ? $doc_fields[$solr_property] : [
$doc_fields[$solr_property],
];
$field = clone $fields[$search_api_property];
foreach ($doc_field as &$value) {
// The prefixes returned by Utility::getDataTypeInfo() are suitable
// even for non Drupal Solr Documents here.
$type_info = Utility::getDataTypeInfo($field
->getType()) + [
'prefix' => '_',
];
switch (substr($type_info['prefix'], 0, 1)) {
case 'd':
// Field type convertions
// Date fields need some special treatment to become valid date
// values (i.e., timestamps) again.
if (preg_match('/^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}Z$/', $value)) {
$value = strtotime($value);
}
break;
case 't':
$value = new TextValue($value);
}
}
unset($value);
$field
->setValues($doc_field);
$result_item
->setField($search_api_property, $field);
}
}
$solr_id = Utility::hasIndexJustSolrDatasources($index) ? str_replace('solr_document/', '', $result_item
->getId()) : $this
->createId($this
->getTargetedSiteHash($index), $this
->getTargetedIndexId($index), $result_item
->getId());
$this
->getHighlighting($result
->getData(), $solr_id, $result_item, $field_names);
$result_set
->addResultItem($result_item);
}
return $result_set;
}