You are here

protected function Database::setQuerySort in Search API 8

Adds the appropriate "ORDER BY" statements to a search database query.

Parameters

\Drupal\search_api\Query\QueryInterface $query: The search query whose sorts should be applied.

\Drupal\Core\Database\Query\SelectInterface $db_query: The database query constructed for the search.

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

Throws

\Drupal\search_api\SearchApiException Thrown if an illegal sort was specified.

1 call to Database::setQuerySort()
Database::search in modules/search_api_db/src/Plugin/search_api/backend/Database.php
Executes a search on this server.

File

modules/search_api_db/src/Plugin/search_api/backend/Database.php, line 2389

Class

Database
Indexes and searches items using the database.

Namespace

Drupal\search_api_db\Plugin\search_api\backend

Code

protected function setQuerySort(QueryInterface $query, SelectInterface $db_query, array $fields) {
  $sort = $query
    ->getSorts();
  if ($sort) {
    $db_fields = $db_query
      ->getFields();
    foreach ($sort as $field_name => $order) {
      if ($order != QueryInterface::SORT_ASC && $order != QueryInterface::SORT_DESC) {
        $msg = $this
          ->t('Unknown sort order @order. Assuming "@default".', [
          '@order' => $order,
          '@default' => QueryInterface::SORT_ASC,
        ]);
        $this->warnings[(string) $msg] = 1;
        $order = QueryInterface::SORT_ASC;
      }
      if ($field_name == 'search_api_relevance') {
        $db_query
          ->orderBy('score', $order);
        continue;
      }
      if ($field_name == 'search_api_random') {
        $this->dbmsCompatibility
          ->orderByRandom($db_query);
        continue;
      }
      if (!isset($fields[$field_name])) {
        throw new SearchApiException("Trying to sort on unknown field '{$field_name}'.");
      }
      $index_table = $this
        ->getIndexDbInfo($query
        ->getIndex())['index_table'];
      $alias = $this
        ->getTableAlias([
        'table' => $index_table,
      ], $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');
  }
}