You are here

protected function SearchApiSolrBackend::extractFacets in Search API Solr 8.3

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

Extracts facets from a Solarium result set.

Parameters

\Drupal\search_api\Query\QueryInterface $query: The search query.

\Solarium\QueryType\Select\Result\Result $resultset: A Solarium select response object.

Return value

array An array describing facets that apply to the current results.

Throws

\Drupal\Component\Plugin\Exception\PluginException

\Drupal\search_api\SearchApiException

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

Class

SearchApiSolrBackend
Apache Solr backend for search api.

Namespace

Drupal\search_api_solr\Plugin\search_api\backend

Code

protected function extractFacets(QueryInterface $query, Result $resultset) {
  if (!$resultset
    ->getFacetSet()) {
    return [];
  }
  $field_names = $this
    ->getSolrFieldNames($query
    ->getIndex());
  $connector = $this
    ->getSolrConnector();
  $solr_version = $connector
    ->getSolrVersion();
  $facets = [];
  $index = $query
    ->getIndex();
  $fields = $index
    ->getFields();
  $extract_facets = $query
    ->getOption('search_api_facets', []);
  if ($facet_fields = $resultset
    ->getFacetSet()
    ->getFacets()) {
    foreach ($extract_facets as $delta => $info) {
      $field = $field_names[$info['field']];
      if (!empty($facet_fields[$field])) {
        $min_count = $info['min_count'];
        $terms = $facet_fields[$field]
          ->getValues();
        if ($info['missing']) {

          // We have to correctly incorporate the "_empty_" term.
          // This will ensure that the term with the least results is dropped,
          // if the limit would be exceeded.
          if (isset($terms[''])) {
            if ($terms[''] < $min_count) {
              unset($terms['']);
            }
            else {
              arsort($terms);
              if ($info['limit'] > 0 && count($terms) > $info['limit']) {
                array_pop($terms);
              }
            }
          }
        }
        elseif (isset($terms[''])) {
          unset($terms['']);
        }
        $type = isset($fields[$info['field']]) ? $fields[$info['field']]
          ->getType() : 'string';
        foreach ($terms as $term => $count) {
          if ($count >= $min_count) {
            if ($term === '') {
              $term = '!';
            }
            elseif ($type === 'boolean') {
              if ($term === 'true') {
                $term = '"1"';
              }
              elseif ($term === 'false') {
                $term = '"0"';
              }
            }
            elseif ($type === 'date') {
              $term = $term ? '"' . strtotime($term) . '"' : NULL;
            }
            else {
              $term = "\"{$term}\"";
            }
            if ($term) {
              $facets[$delta][] = [
                'filter' => $term,
                'count' => $count,
              ];
            }
          }
        }
        if (empty($facets[$delta])) {
          unset($facets[$delta]);
        }
      }
    }
  }
  $result_data = $resultset
    ->getData();
  if (isset($result_data['facet_counts']['facet_queries'])) {
    $spatials = $query
      ->getOption('search_api_location');
    if ($spatials !== NULL) {
      foreach ($result_data['facet_counts']['facet_queries'] as $key => $count) {

        // This special key is defined in setSpatial().
        if (!preg_match('/^spatial-(.*)-(\\d+(?:\\.\\d+)?)-(\\d+(?:\\.\\d+)?)$/', $key, $matches)) {
          continue;
        }
        if (empty($extract_facets[$matches[1]])) {
          continue;
        }
        $facet = $extract_facets[$matches[1]];
        if ($count >= $facet['min_count']) {
          $facets[$matches[1]][] = [
            'filter' => "[{$matches[2]} {$matches[3]}]",
            'count' => $count,
          ];
        }
      }
    }
  }

  // Extract heatmaps.
  if (isset($result_data['facet_counts']['facet_heatmaps'])) {
    $spatials = $query
      ->getOption('search_api_rpt');
    if ($spatials !== NULL) {
      foreach ($result_data['facet_counts']['facet_heatmaps'] as $key => $value) {
        if (!preg_match('/^rpts_(.*)$/', $key, $matches)) {
          continue;
        }
        if (empty($extract_facets[$matches[1]])) {
          continue;
        }
        $heatmaps = [];
        if (version_compare($solr_version, '7.5', '>=')) {
          $heatmaps = $value['counts_ints2D'];
        }
        else {
          $heatmaps = array_slice($value, 15);
        }
        $heatmap = [];
        array_walk_recursive($heatmaps, function ($heatmaps) use (&$heatmap) {
          $heatmap[] = $heatmaps;
        });
        $count = array_sum($heatmap);
        $facets[$matches[1]][] = [
          'filter' => $value,
          'count' => $count,
        ];
      }
    }
  }
  return $facets;
}