You are here

protected function SearchBuilder::setMoreLikeThisQuery in Elasticsearch Connector 8.6

Same name and namespace in other branches
  1. 8.7 src/ElasticSearch/Parameters/Builder/SearchBuilder.php \Drupal\elasticsearch_connector\ElasticSearch\Parameters\Builder\SearchBuilder::setMoreLikeThisQuery()
  2. 8.5 src/ElasticSearch/Parameters/Builder/SearchBuilder.php \Drupal\elasticsearch_connector\ElasticSearch\Parameters\Builder\SearchBuilder::setMoreLikeThisQuery()

Setup the More like this clause of the Elasticsearch query.

Adjusts $this->body to have a more like this query.

Parameters

array $query_options: Array of query options. We're most interested here in the key of 'mlt', which should contain the following keys:

  • id: To be used as the like_text in the more_like_this query.
  • fields: Array of fields.
1 call to SearchBuilder::setMoreLikeThisQuery()
SearchBuilder::build in src/ElasticSearch/Parameters/Builder/SearchBuilder.php
Build up the body of the request to the Elasticsearch _search endpoint.

File

src/ElasticSearch/Parameters/Builder/SearchBuilder.php, line 513

Class

SearchBuilder
Class SearchBuilder.

Namespace

Drupal\elasticsearch_connector\ElasticSearch\Parameters\Builder

Code

protected function setMoreLikeThisQuery(array $query_options) {
  if (!empty($query_options['mlt'])) {
    $mlt_query['more_like_this'] = [];

    // Transform input parameter "id" to "ids" if available.
    if (isset($query_options['mlt']['id'])) {
      $query_options['mlt']['ids'] = is_array($query_options['mlt']['id']) ? $query_options['mlt']['id'] : [
        $query_options['mlt']['id'],
      ];
      unset($query_options['mlt']['id']);
    }
    $language_ids = $this->query
      ->getLanguages();
    if (empty($language_ids)) {

      // If the query isn't already restricted by languages we have to do it
      // here in order to limit the MLT suggestions to be of the same language
      // as the currently shown one.
      $language_ids[] = \Drupal::languageManager()
        ->getCurrentLanguage(LanguageInterface::TYPE_CONTENT)
        ->getId();

      // For non-translatable entity types, add the "not specified" language to
      // the query so they also appear in the results.
      $language_ids[] = LanguageInterface::LANGCODE_NOT_SPECIFIED;
      $this->query
        ->setLanguages($language_ids);
    }
    foreach ($query_options['mlt']['ids'] as $id) {
      foreach ($this->index
        ->getDatasources() as $datasource) {
        if ($entity_type_id = $datasource
          ->getEntityTypeId()) {
          $entity = \Drupal::entityTypeManager()
            ->getStorage($entity_type_id)
            ->load($id);
          if ($entity instanceof ContentEntityInterface) {
            $translated = FALSE;
            if ($entity
              ->isTranslatable()) {
              foreach ($language_ids as $language_id) {
                if ($entity
                  ->hasTranslation($language_id)) {
                  $ids[] = SearchApiUtility::createCombinedId($datasource
                    ->getPluginId(), $datasource
                    ->getItemId($entity
                    ->getTranslation($language_id)
                    ->getTypedData()));
                  $translated = TRUE;
                }
              }
            }
            if (!$translated) {

              // Fall back to the default language of the entity.
              $ids[] = SearchApiUtility::createCombinedId($datasource
                ->getPluginId(), $datasource
                ->getItemId($entity
                ->getTypedData()));
            }
          }
          else {
            $ids[] = $id;
          }
        }
      }
    }

    // Input parameter: ids
    if (!empty($ids)) {
      $mlt_query['more_like_this']['like'] = [];
      foreach ($ids as $id) {
        $mlt_query['more_like_this']['like'][] = [
          '_index' => IndexFactory::getIndexName($this->index),
          '_type' => '_doc',
          '_id' => $id,
        ];
      }
    }

    // Input parameter: like
    if (isset($query_options['mlt']['like'])) {
      $mlt_query['more_like_this']['like'] = $query_options['mlt']['like'];
    }

    // Input parameter: unlike
    if (isset($query_options['mlt']['unlike'])) {
      $mlt_query['more_like_this']['unlike'] = $query_options['mlt']['unlike'];
    }

    // Input parameter: fields
    $mlt_query['more_like_this']['fields'] = array_values($query_options['mlt']['fields']);

    // TODO: Make this settings configurable in the view.
    $mlt_query['more_like_this']['max_query_terms'] = 1;
    $mlt_query['more_like_this']['min_doc_freq'] = 1;
    $mlt_query['more_like_this']['min_term_freq'] = 1;
    $this->body['query']['bool']['must'][] = $mlt_query;
  }
}