You are here

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

\Drupal\search_api\Query\QueryInterface $query: The Search API query to build the mlt query from.

Return value

\Solarium\QueryType\MorelikeThis\Query The Solarium MorelikeThis query.

Throws

\Drupal\Component\Plugin\Exception\PluginException

\Drupal\search_api\SearchApiException

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 4093

Class

SearchApiSolrBackend
Apache Solr backend for search api.

Namespace

Drupal\search_api_solr\Plugin\search_api\backend

Code

protected function getMoreLikeThisQuery(QueryInterface $query) {
  $connector = $this
    ->getSolrConnector();
  $solarium_query = $connector
    ->getMoreLikeThisQuery();
  $mlt_options = $query
    ->getOption('search_api_mlt');
  $language_ids = $this
    ->ensureLanguageCondition($query);
  $field_names = $this
    ->getSolrFieldNamesKeyedByLanguage($language_ids, $query
    ->getIndex());
  $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)) {
    $index = $query
      ->getIndex();
    $index_id = $this
      ->getTargetedIndexId($index);
    $site_hash = $this
      ->getTargetedSiteHash($index);
    if (!Utility::hasIndexJustSolrDatasources($index)) {
      array_walk($ids, function (&$id, $key) use ($site_hash, $index_id) {
        $id = $this
          ->createId($site_hash, $index_id, $id);
        $id = $this->queryHelper
          ->escapePhrase($id);
      });
    }
    $solarium_query
      ->setQuery('id:' . implode(' id:', $ids));
  }
  $mlt_fl = [];
  foreach ($mlt_options['fields'] as $mlt_field) {
    $first_field = reset($field_names[$mlt_field]);

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

        // Non-text fields are not language-specific.
        $mlt_fl[] = [
          $first_field,
        ];
      }
      else {

        // Add all language-specific field names. This should work for
        // non Drupal Solr Documents as well which contain only a single
        // name.
        $mlt_fl[] = array_values($field_names[$mlt_field]);
      }
    }
  }
  $settings = Utility::getIndexSolrSettings($query
    ->getIndex());
  $solarium_query
    ->setMltFields(array_merge(...$mlt_fl))
    ->setMinimumTermFrequency($settings['mlt']['mintf'])
    ->setMinimumDocumentFrequency($settings['mlt']['mindf'])
    ->setMaximumQueryTerms($settings['mlt']['maxqt'])
    ->setMaximumNumberOfTokens($settings['mlt']['maxntp'])
    ->setBoost($settings['mlt']['boost'])
    ->setInterestingTerms($settings['mlt']['interestingTerms']);
  if ($settings['mlt']['maxdf']) {
    $solarium_query
      ->addParam('mlt.maxdf', $settings['mlt']['maxdf']);
  }
  if ($settings['mlt']['maxdfpct']) {
    $solarium_query
      ->addParam('mlt.maxdf', $settings['mlt']['maxdfpct']);
  }
  if ($settings['mlt']['minwl']) {
    $solarium_query
      ->setMinimumWordLength($settings['mlt']['minwl']);
  }
  if ($settings['mlt']['maxwl']) {
    $solarium_query
      ->setMaximumWordLength($settings['mlt']['maxwl']);
  }
  return $solarium_query;
}