You are here

protected function SearchApiSolrBackend::getMoreLikeThisQuery in Search API Solr 8.2

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::getMoreLikeThisQuery()
  2. 8 src/Plugin/search_api/backend/SearchApiSolrBackend.php \Drupal\search_api_solr\Plugin\search_api\backend\SearchApiSolrBackend::getMoreLikeThisQuery()
  3. 4.x src/Plugin/search_api/backend/SearchApiSolrBackend.php \Drupal\search_api_solr\Plugin\search_api\backend\SearchApiSolrBackend::getMoreLikeThisQuery()

Changes the query to a "More Like This" query.

Parameters

\Solarium\QueryType\MorelikeThis\Query $solarium_query: The solr mlt query.

string $index_id: Solr specific index ID.

array $index_fields: The fields in the index to add mlt for.

array $fields: The fields to add mlt for.

Return value

\Solarium\QueryType\MorelikeThis\Query $solarium_query

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

Class

SearchApiSolrBackend
Apache Solr backend for search api.

Namespace

Drupal\search_api_solr\Plugin\search_api\backend

Code

protected function getMoreLikeThisQuery(QueryInterface $query, $index_id, $index_fields = [], $fields = []) {
  $connector = $this
    ->getSolrConnector();
  $solarium_query = $connector
    ->getMoreLikeThisQuery();
  $mlt_options = $query
    ->getOption('search_api_mlt');
  $language_ids = $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;
    $query
      ->setLanguages($language_ids);
  }
  $ids = [];
  foreach ($query
    ->getIndex()
    ->getDatasources() as $datasource) {
    if ($entity_type_id = $datasource
      ->getEntityTypeId()) {
      $entity = \Drupal::entityTypeManager()
        ->getStorage($entity_type_id)
        ->load($mlt_options['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[] = $mlt_options['id'];
      }
    }
  }
  if (!empty($ids)) {
    array_walk($ids, function (&$id, $key) use ($index_id) {
      $id = $this
        ->createId($index_id, $id);
      $id = $this->queryHelper
        ->escapePhrase($id);
    });
    $solarium_query
      ->setQuery('id:' . implode(' id:', $ids));
  }
  $mlt_fl = [];
  foreach ($mlt_options['fields'] as $mlt_field) {

    // Date fields don't seem to be supported at all in MLT queries.
    if (strpos($mlt_field, 'd') !== 0) {
      $mlt_fl[] = $fields[$mlt_field];

      // For non-text fields, set minimum word length to 0.
      if (isset($index_fields[$mlt_field]) && !$this->dataTypeHelper
        ->isTextType($index_fields[$mlt_field]
        ->getType())) {
        $solarium_query
          ->addParam('f.' . $fields[$mlt_field] . '.mlt.minwl', 0);
      }
    }
  }
  $solarium_query
    ->setMltFields($mlt_fl);

  // @todo Add some configuration options here and support more MLT options.
  $solarium_query
    ->setMinimumDocumentFrequency(1);
  $solarium_query
    ->setMinimumTermFrequency(1);
  return $solarium_query;
}