You are here

protected function SearchApiSolrService::extractResults in Search API Solr 7

Extract results from a Solr response.

Parameters

object $response: A HTTP response object.

Return value

array An array with two keys:

1 call to SearchApiSolrService::extractResults()
SearchApiSolrService::search in includes/service.inc
Executes a search on the server represented by this object.

File

includes/service.inc, line 1292

Class

SearchApiSolrService
Search service class using Solr server.

Code

protected function extractResults(SearchApiQueryInterface $query, $response) {
  $index = $query
    ->getIndex();
  $fields = $this
    ->getFieldNames($index);
  $field_options = $index->options['fields'];
  $version = $this->solr
    ->getSolrVersion();

  // Set up the results array.
  $results = array();
  $results['results'] = array();

  // Keep a copy of the response in the results so it's possible to extract
  // further useful information out of it, if necessary.
  $results['search_api_solr_response'] = $response;

  // In some rare cases (e.g., MLT query with nonexistent ID) the response
  // will be NULL.
  if (!isset($response->response) && !isset($response->grouped)) {
    $results['result count'] = 0;
    return $results;
  }

  // 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']) && !empty($response->grouped)) {
    $docs = array();
    $results['result count'] = 0;
    foreach ($grouping['fields'] as $field) {
      if (!empty($response->grouped->{$fields[$field]})) {
        $results['result count'] += $response->grouped->{$fields[$field]}->ngroups;
        foreach ($response->grouped->{$fields[$field]}->groups as $group) {
          foreach ($group->doclist->docs as $doc) {
            $docs[] = $doc;
          }
        }
      }
    }
  }
  else {
    $results['result count'] = $response->response->numFound;
    $docs = $response->response->docs;
  }
  $spatials = $query
    ->getOption('search_api_location');

  // Add each search result to the results array.
  foreach ($docs as $doc) {

    // Blank result array.
    $result = array(
      'id' => NULL,
      'score' => NULL,
      'fields' => array(),
    );

    // Extract properties from the Solr document, translating from Solr to
    // Search API property names. This reverses the mapping in
    // SearchApiSolrService::getFieldNames().
    foreach ($fields as $search_api_property => $solr_property) {
      if (isset($doc->{$solr_property})) {
        $value = $doc->{$solr_property};

        // Date fields need some special treatment to become valid date values
        // (i.e., timestamps) again.
        $first_value = $value;
        while (is_array($first_value)) {
          $first_value = reset($first_value);
        }
        if (isset($field_options[$search_api_property]['type']) && search_api_extract_inner_type($field_options[$search_api_property]['type']) === 'date' && preg_match('/^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}Z$/', $first_value)) {
          $value = is_array($value) ? array_map('strtotime', $value) : strtotime($value);
        }
        $result['fields'][$search_api_property] = $value;
      }
    }

    // We can find the item id and score in the special 'search_api_*'
    // properties. Mappings are provided for these properties in
    // SearchApiSolrService::getFieldNames().
    $result['id'] = $result['fields']['search_api_id'];
    $result['score'] = $result['fields']['search_api_relevance'];

    // If location based search is enabled ensure the calculated distance is
    // set to the appropriate field. If the calculation wasn't possible add
    // the coordinates to allow calculation.
    if ($spatials) {
      foreach ($spatials as $spatial) {
        if (isset($spatial['field']) && !empty($spatial['distance'])) {
          if ($version >= 4) {
            $doc_field = '_' . $fields[$spatial['field']] . '_distance_';
            if (!empty($doc->{$doc_field})) {
              $results['search_api_location'][$spatial['field']][$result['id']]['distance'] = $doc->{$doc_field};
            }
          }
        }
      }
    }
    $index_id = $this
      ->getIndexId($index->machine_name);
    $solr_id = $this
      ->createId($index_id, $result['id']);
    $excerpt = $this
      ->getExcerpt($response, $solr_id, $result['fields'], $fields, $this
      ->getQueryFields($query));
    if ($excerpt) {
      $result['excerpt'] = $excerpt;
    }

    // Use the result's id as the array key. By default, 'id' is mapped to
    // 'item_id' in SearchApiSolrService::getFieldNames().
    if ($result['id']) {
      $results['results'][$result['id']] = $result;
    }
  }

  // Check for spellcheck suggestions.
  if (module_exists('search_api_spellcheck') && $query
    ->getOption('search_api_spellcheck')) {
    $results['search_api_spellcheck'] = new SearchApiSpellcheckSolr($response);
  }
  return $results;
}