You are here

protected function SarniaSolrService::extractResults in Sarnia 7

Extract results from a Solr response.

Parameters

object $response: A HTTP response object.

Return value

array An array with two keys:

Overrides SearchApiSolrService::extractResults

File

./service.inc, line 423

Class

SarniaSolrService
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->{$field})) {
        $results['result count'] += $response->grouped->{$field}->ngroups;
        foreach ($response->grouped->{$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})) {
        $result['fields'][$search_api_property] = $doc->{$solr_property};

        // Date fields need some special treatment to become valid date values
        // (i.e., timestamps) again.
        if (isset($field_options[$search_api_property]['type']) && $field_options[$search_api_property]['type'] == 'date') {

          // Date fields with multiple values are represented as an array not a string
          if (!is_array($result['fields'][$search_api_property])) {
            if (preg_match('/^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}Z$/', $result['fields'][$search_api_property])) {
              $result['fields'][$search_api_property] = strtotime($result['fields'][$search_api_property]);
            }
          }
          else {
            $date_values = array_values($result['fields'][$search_api_property]);
            for ($i = 0; $i < count($date_values); $i++) {
              if (preg_match('/^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}Z$/', $date_values[$i])) {
                $result['fields'][$search_api_property][$i] = strtotime($date_values[$i]);
              }
            }
          }
        }
      }
    }

    // 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};
            }
          }
        }
      }
    }
    $excerpt = $this
      ->getExcerpt($response, $result['fields']['id'], $result['fields'], $fields, $query
      ->getFields());
    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;
}