You are here

protected function SearchApiSolrBackend::setFacets in Search API Solr 4.x

Same name and namespace in other branches
  1. 8.3 src/Plugin/search_api/backend/SearchApiSolrBackend.php \Drupal\search_api_solr\Plugin\search_api\backend\SearchApiSolrBackend::setFacets()
  2. 8 src/Plugin/search_api/backend/SearchApiSolrBackend.php \Drupal\search_api_solr\Plugin\search_api\backend\SearchApiSolrBackend::setFacets()
  3. 8.2 src/Plugin/search_api/backend/SearchApiSolrBackend.php \Drupal\search_api_solr\Plugin\search_api\backend\SearchApiSolrBackend::setFacets()

Helper method for creating the facet field parameters.

Parameters

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

\Solarium\QueryType\Select\Query\Query $solarium_query: The Solarium query.

Throws

\Drupal\search_api\SearchApiException

\Drupal\search_api_solr\SearchApiSolrException

1 call to SearchApiSolrBackend::setFacets()
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:

File

src/Plugin/search_api/backend/SearchApiSolrBackend.php, line 3363

Class

SearchApiSolrBackend
Apache Solr backend for search api.

Namespace

Drupal\search_api_solr\Plugin\search_api\backend

Code

protected function setFacets(QueryInterface $query, Query $solarium_query) {
  static $index_fulltext_fields = [];
  $this->eventDispatcher
    ->dispatch(new PreSetFacetsEvent($query, $solarium_query));
  $facets = $query
    ->getOption('search_api_facets', []);
  if (empty($facets)) {
    return;
  }
  $index = $query
    ->getIndex();
  $index_id = $index
    ->id();
  $field_names = $this
    ->getSolrFieldNames($index);
  $facet_set = $solarium_query
    ->getFacetSet();
  $facet_set
    ->setSort('count');
  $facet_set
    ->setLimit(10);
  $facet_set
    ->setMinCount(1);
  $facet_set
    ->setMissing(FALSE);
  foreach ($facets as $info) {
    if (empty($field_names[$info['field']])) {
      continue;
    }
    $solr_field = $field_names[$info['field']];
    $facet_field = NULL;

    // Backward compatibility for facets.
    $info += [
      'query_type' => 'search_api_string',
    ];
    switch ($info['query_type']) {
      case 'search_api_granular':
        $facet_field = $facet_set
          ->createFacetRange([
          'local_key' => $solr_field,
          'field' => $solr_field,
          'start' => $info['min_value'],
          'end' => $info['max_value'],
          'gap' => $info['granularity'],
        ]);
        $includes = [];
        if ($info['include_lower']) {
          $includes[] = 'lower';
        }
        if ($info['include_upper']) {
          $includes[] = 'upper';
        }
        if ($info['include_edges']) {
          $includes[] = 'edge';
        }
        $facet_field
          ->setInclude($includes);
        break;
      case 'search_api_string':
      default:
        if (!isset($index_fulltext_fields[$index_id])) {
          $index_fulltext_fields[$index_id] = $index
            ->getFulltextFields();
        }
        if (in_array($info['field'], $index_fulltext_fields[$index_id])) {

          // @todo For sure Solr can handle it. But it was a trade-off for
          //   3.x. For full multilingual support, fulltext fields are
          //   indexed in language specific fields. In case of facets it is
          //   hard to detect which language specific fields should be
          //   considered. And the results have to be combined across
          //   languages. One way to implement it might be facet queries.
          throw new SearchApiSolrException('Facetting on fulltext fields is not yet supported. Consider to add a string field to the index for that purpose.');
        }
        else {

          // Create the Solarium facet field object.
          $facet_field = $facet_set
            ->createFacetField($solr_field)
            ->setField($solr_field);
        }

        // Set limit, unless it's the default.
        if ($info['limit'] != 10) {
          $limit = $info['limit'] ? $info['limit'] : -1;
          $facet_field
            ->setLimit($limit);
        }

        // Set missing, if specified.
        if ($info['missing']) {
          $facet_field
            ->setMissing(TRUE);
        }
        else {
          $facet_field
            ->setMissing(FALSE);
        }
    }

    // For "OR" facets, add the expected tag for exclusion.
    if (isset($info['operator']) && strtolower($info['operator']) === 'or') {

      // The tag "facet:field_name" is defined by the facets module. Therefore
      // we have to use the Search API field name here to create the same tag.
      // @see \Drupal\facets\QueryType\QueryTypeRangeBase::execute()
      // @see https://cwiki.apache.org/confluence/display/solr/Faceting#Faceting-LocalParametersforFaceting
      $facet_field
        ->getLocalParameters()
        ->clearExcludes()
        ->addExcludes([
        'facet:' . $info['field'],
      ]);
    }

    // Set mincount, unless it's the default.
    if ($info['min_count'] != 1) {
      $facet_field
        ->setMinCount($info['min_count']);
    }
  }
  $this->eventDispatcher
    ->dispatch(new PostSetFacetsEvent($query, $solarium_query));
}