You are here

public static function Utility::getSortableSolrField in Search API Solr 4.x

Same name and namespace in other branches
  1. 8.3 src/Utility/Utility.php \Drupal\search_api_solr\Utility\Utility::getSortableSolrField()

Gets the sortable equivalent of a dynamic Solr field.

Parameters

string $field_name: The Search API field name.

array $solr_field_names: The dynamic Solr field names.

\Drupal\search_api\Query\QueryInterface $query: The Search API query.

Return value

string The sortable Solr field name.

Throws

\Drupal\search_api_solr\SearchApiSolrException

3 calls to Utility::getSortableSolrField()
SearchApiSolrBackend::search in src/Plugin/search_api/backend/SearchApiSolrBackend.php
Options on $query prefixed by 'solr_param_' will be passed natively to Solr as query parameter without the prefix. For example you can set the "Minimum Should Match" parameter 'mm' to '75%' like this:
SearchApiSolrBackend::setGrouping in src/Plugin/search_api/backend/SearchApiSolrBackend.php
Sets grouping for the query.
SearchApiSolrBackend::setSorts in src/Plugin/search_api/backend/SearchApiSolrBackend.php
Sets sorting for the query.

File

src/Utility/Utility.php, line 551

Class

Utility
Provides various helper functions for Solr backends.

Namespace

Drupal\search_api_solr\Utility

Code

public static function getSortableSolrField(string $field_name, array $solr_field_names, QueryInterface $query) {
  if (!isset($solr_field_names[$field_name])) {
    throw new SearchApiSolrException(sprintf('Sort "%s" is not valid solr field.', $field_name));
  }
  $first_solr_field_name = reset($solr_field_names[$field_name]);
  if (Utility::hasIndexJustSolrDocumentDatasource($query
    ->getIndex())) {
    return $first_solr_field_name;
  }

  // First we need to handle special fields which are prefixed by
  // 'search_api_'. Otherwise they will erroneously be treated as dynamic
  // string fields by the next detection below because they start with an
  // 's'. This way we for example ensure that search_api_relevance isn't
  // modified at all.
  if (strpos($field_name, 'search_api_') === 0) {
    if ('search_api_random' === $field_name) {

      // The default Solr schema provides a virtual field named "random_*"
      // that can be used to randomly sort the results; the field is
      // available only at query-time. See schema.xml for more details about
      // how the "seed" works.
      $params = $query
        ->getOption('search_api_random_sort', []);

      // Random seed: getting the value from parameters or computing a new
      // one.
      $seed = !empty($params['seed']) ? $params['seed'] : mt_rand();
      return $first_solr_field_name . '_' . $seed;
    }
  }
  elseif (strpos($first_solr_field_name, 'spellcheck') === 0 || strpos($first_solr_field_name, 'twm_suggest') === 0) {
    throw new SearchApiSolrException("You can't sort by spellcheck or suggester catalogs.");
  }
  elseif (strpos($first_solr_field_name, 's') === 0 || strpos($first_solr_field_name, 't') === 0) {

    // For string and fulltext fields use the dedicated sort field for faster
    // and language specific sorts. If multiple languages are specified, use
    // the first one.
    $language_ids = $query
      ->getLanguages() ?? [
      LanguageInterface::LANGCODE_NOT_SPECIFIED,
    ];
    return Utility::encodeSolrName('sort' . SolrBackendInterface::SEARCH_API_SOLR_LANGUAGE_SEPARATOR . reset($language_ids) . '_' . $field_name);
  }
  elseif (preg_match('/^([a-z]+)m(_.*)/', $first_solr_field_name, $matches)) {

    // For other multi-valued fields (which aren't sortable by nature) we
    // use the same hackish workaround like the DB backend: just copy the
    // first value in a single value field for sorting.
    return $matches[1] . 's' . $matches[2];
  }

  // We could not simply put this into an else condition because that would
  // miss fields like search_api_relevance.
  return $first_solr_field_name;
}