You are here

protected function SearchApiDbService::setQuerySort in Search API Database Search 7

Adds the query sort to a search database query.

Parameters

SearchApiQueryInterface $query: The search query whose sorts should be applied.

SelectQueryInterface $db_query: The database query used for the search.

array $fields: An array containing information about the internal server storage of the indexed fields.

Throws

SearchApiException If an illegal sort was specified.

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

File

./service.inc, line 1857
Contains SearchApiDbService.

Class

SearchApiDbService
Indexes and searches items using the database.

Code

protected function setQuerySort(SearchApiQueryInterface $query, SelectQueryInterface $db_query, array $fields) {
  $sort = $query
    ->getSort();
  if ($sort) {
    foreach ($sort as $field_name => $order) {
      if ($order != 'ASC' && $order != 'DESC') {
        $msg = t('Unknown sort order @order. Assuming "ASC".', array(
          '@order' => $order,
        ));
        $this->warnings[$msg] = $msg;
        $order = 'ASC';
      }
      if ($field_name == 'search_api_relevance') {
        $db_query
          ->orderBy('score', $order);
        continue;
      }
      if ($field_name == 'search_api_id') {
        $db_query
          ->orderBy('item_id', $order);
        continue;
      }
      if ($field_name == 'search_api_random') {
        $db_query
          ->orderRandom();
        continue;
      }
      if (!isset($fields[$field_name])) {
        throw new SearchApiException(t('Trying to sort on unknown field @field.', array(
          '@field' => $field_name,
        )));
      }
      $field = $fields[$field_name];
      if (search_api_is_list_type($field['type'])) {
        throw new SearchApiException(t('Cannot sort on field @field of a list type.', array(
          '@field' => $field_name,
        )));
      }
      if (search_api_is_text_type($field['type'])) {
        throw new SearchApiException(t('Cannot sort on fulltext field @field.', array(
          '@field' => $field_name,
        )));
      }
      $alias = $this
        ->getTableAlias($field, $db_query);
      $db_query
        ->orderBy($alias . '.' . $fields[$field_name]['column'], $order);

      // PostgreSQL automatically adds a field to the SELECT list when sorting
      // on it. Therefore, if we have aggregations present we also have to
      // add the field to the GROUP BY (since Drupal won't do it for us).
      // However, if no aggregations are present, a GROUP BY would lead to
      // another error. Therefore, we only add it if there is already a GROUP
      // BY.
      if ($db_query
        ->getGroupBy()) {
        $db_query
          ->groupBy($alias . '.' . $fields[$field_name]['column']);
      }

      // For SELECT DISTINCT queries in combination with an ORDER BY clause,
      // MySQL 5.7 and higher require that the ORDER BY expressions are part
      // of the field list. Ensure that all fields used for sorting are part
      // of the select list.
      if (empty($db_fields[$fields[$field_name]['column']])) {
        $db_query
          ->addField($alias, $fields[$field_name]['column']);
      }
    }
  }
  else {
    $db_query
      ->orderBy('score', 'DESC');
  }
}