/** * Extract results from a Solr response. * * @param \Drupal\search_api\Query\QueryInterface $query * The Search API query object. * @param \Solarium\Core\Query\Result\ResultInterface $result * A Solarium select response object. * * @return \Drupal\search_api\Query\ResultSetInterface * A result set object. */ protected function extractResults(QueryInterface $query, ResultInterface $result) { $index = $query->getIndex(); $field_names = $this->getFieldNames($index); $fields = $index->getFields(); $site_hash = SearchApiSolrUtility::getSiteHash(); // We can find the item ID and the score in the special 'search_api_*' // properties. Mappings are provided for these properties in // SearchApiSolrBackend::getFieldNames(). $id_field = $field_names['search_api_id']; $score_field = $field_names['search_api_relevance']; // Set up the results array. $result_set = SearchApiUtility::createSearchResultSet($query); $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'); $docs = array(); if (!empty($grouping['use_grouping']) && $is_grouping) { // $docs = array(); // $result_set['result count'] = 0; // foreach ($grouping['fields'] as $field) { // if (!empty($response->grouped->{$fields[$field]})) { // $result_set['result count'] += $response->grouped->{$fields[$field]}->ngroups; // foreach ($response->grouped->{$fields[$field]}->groups as $group) { // foreach ($group->doclist->docs as $doc) { // $docs[] = $doc; // } // } // } // } } 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) { $doc_fields = $doc->getFields(); $item_id = $doc_fields[$id_field]; // For items coming from a different site, we need to adapt the item ID. if (!$this->configuration['site_hash'] && $doc_fields['hash'] != $site_hash) { $item_id = $doc_fields['hash'] . '--' . $item_id; } $result_item = SearchApiUtility::createItem($index, $item_id); $result_item->setScore($doc_fields[$score_field]); unset($doc_fields[$id_field], $doc_fields[$score_field]); // Extract properties from the Solr document, translating from Solr to // Search API property names. This reverses the mapping in // SearchApiSolrBackend::getFieldNames(). foreach ($field_names as $search_api_property => $solr_property) { if (isset($doc_fields[$solr_property])) { // Date fields need some special treatment to become valid date values // (i.e., timestamps) again. if (isset($fields[$search_api_property]) && $fields[$search_api_property]->getType() == 'date' && preg_match('/^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}Z$/', $doc_fields[$solr_property][0])) { $doc_fields[$solr_property][0] = strtotime($doc_fields[$solr_property][0]); } $field = SearchApiUtility::createField($index, $search_api_property); $field->setValues($doc_fields[$solr_property]); $result_item->setField($search_api_property, $field); } } $index_id = $this->getIndexId($index->id()); $solr_id = $this->createId($index_id, $result_item->getId()); $item_fields = $result_item->getFields(); $excerpt = $this->getSolrHelper()->getExcerpt($result->getData(), $solr_id, $item_fields, $field_names); if ($excerpt) { $result_item->setExcerpt($excerpt); } $result_set->addResultItem($result_item); } // Check for spellcheck suggestions. /*if (module_exists('search_api_spellcheck') && $query->getOption('search_api_spellcheck')) { $result_set->setExtraData('search_api_spellcheck', new SearchApiSpellcheckSolr($result)); }*/ return $result_set; }