You are here

public function SearchApiAlgoliaBackend::search in Search API Algolia 8

Same name and namespace in other branches
  1. 3.0.x src/Plugin/search_api/backend/SearchApiAlgoliaBackend.php \Drupal\search_api_algolia\Plugin\search_api\backend\SearchApiAlgoliaBackend::search()
  2. 2.0.x src/Plugin/search_api/backend/SearchApiAlgoliaBackend.php \Drupal\search_api_algolia\Plugin\search_api\backend\SearchApiAlgoliaBackend::search()

Executes a search on this server.

Parameters

\Drupal\search_api\Query\QueryInterface $query: The query to execute.

Throws

\Drupal\search_api\SearchApiException Thrown if an error prevented the search from completing.

Overrides BackendSpecificInterface::search

File

src/Plugin/search_api/backend/SearchApiAlgoliaBackend.php, line 399

Class

SearchApiAlgoliaBackend
Class SearchApiAlgoliaBackend.

Namespace

Drupal\search_api_algolia\Plugin\search_api\backend

Code

public function search(QueryInterface $query) {
  $results = $query
    ->getResults();
  $options = $query
    ->getOptions();
  $sorts = $query
    ->getSorts() ?? [];
  $search_api_index = $query
    ->getIndex();
  $suffix = '';

  // Allow other modules to remove sorts handled in index rankings.
  $this
    ->getModuleHandler()
    ->alter('search_api_algolia_sorts', $sorts, $search_api_index);

  // Get the first sort to build replica name.
  // Replicas must be created with format PRIMARYINDEXNAME_FIELD_DIRECTION.
  // For instance index_stock_desc.
  foreach ($sorts as $field => $direction) {
    $suffix = '_' . strtolower($field . '_' . $direction);
    break;
  }
  try {
    $this
      ->connect($search_api_index, $suffix);
    $index = $this
      ->getAlgoliaIndex();
  } catch (\Exception $e) {
    $this
      ->getLogger()
      ->error('Failed to connect to Algolia index while searching with suffix: @suffix, Error: @message', [
      '@message' => $e
        ->getMessage(),
      '@suffix' => $suffix,
    ]);
    return $results;
  }
  $facets = isset($options['search_api_facets']) ? array_column($options['search_api_facets'], 'field') : [];
  $algolia_options = [
    'attributesToRetrieve' => [
      'search_api_id',
    ],
    'facets' => $facets,
    'analytics' => TRUE,
  ];
  if (!empty($options['limit'])) {
    $algolia_options['length'] = $options['limit'];
    $algolia_options['offset'] = $options['offset'];
  }
  $this
    ->extractConditions($query
    ->getConditionGroup(), $algolia_options, $facets);

  // Algolia expects indexed arrays, remove the keys.
  if (isset($algolia_options['facetFilters'])) {
    $algolia_options['facetFilters'] = array_values($algolia_options['facetFilters']);
  }
  if (isset($algolia_options['disjunctiveFacets'])) {
    $algolia_options['disjunctiveFacets'] = array_values($algolia_options['disjunctiveFacets']);
  }

  // Filters and disjunctiveFacets are not supported together by Algolia.
  if (!empty($algolia_options['filters']) && !empty($algolia_options['disjunctiveFacets'])) {
    unset($algolia_options['disjunctiveFacets']);
  }
  $keys = $query
    ->getOriginalKeys();
  $search = empty($keys) ? '*' : $keys;
  $data = $index
    ->search($search, $algolia_options);
  $results
    ->setResultCount($data['nbHits']);
  foreach ($data['hits'] ?? [] as $row) {
    $item = $this
      ->getFieldsHelper()
      ->createItem($query
      ->getIndex(), $row['search_api_id']);
    $results
      ->addResultItem($item);
  }
  if (isset($data['facets'])) {
    $results
      ->setExtraData('search_api_facets', $this
      ->extractFacetsData($facets, $data['facets']));
  }
  return $results;
}