public function SearchApiSolrBackend::getDocuments in Search API Solr 8.3
Same name and namespace in other branches
- 8 src/Plugin/search_api/backend/SearchApiSolrBackend.php \Drupal\search_api_solr\Plugin\search_api\backend\SearchApiSolrBackend::getDocuments()
- 8.2 src/Plugin/search_api/backend/SearchApiSolrBackend.php \Drupal\search_api_solr\Plugin\search_api\backend\SearchApiSolrBackend::getDocuments()
- 4.x src/Plugin/search_api/backend/SearchApiSolrBackend.php \Drupal\search_api_solr\Plugin\search_api\backend\SearchApiSolrBackend::getDocuments()
Throws
\Drupal\Component\Plugin\Exception\PluginException
Overrides SolrBackendInterface::getDocuments
2 calls to SearchApiSolrBackend::getDocuments()
- SearchApiSolrBackend::getDocument in src/
Plugin/ search_api/ backend/ SearchApiSolrBackend.php - SearchApiSolrBackend::indexItems in src/
Plugin/ search_api/ backend/ SearchApiSolrBackend.php
File
- src/
Plugin/ search_api/ backend/ SearchApiSolrBackend.php, line 1020
Class
- SearchApiSolrBackend
- Apache Solr backend for search api.
Namespace
Drupal\search_api_solr\Plugin\search_api\backendCode
public function getDocuments(IndexInterface $index, array $items, UpdateQuery $update_query = NULL) {
$documents = [];
$index_id = $this
->getTargetedIndexId($index);
$site_hash = $this
->getTargetedSiteHash($index);
$languages = $this->languageManager
->getLanguages();
$request_time = $this
->formatDate(\Drupal::time()
->getRequestTime());
$base_urls = [];
if (!$update_query) {
$connector = $this
->getSolrConnector();
$update_query = $connector
->getUpdateQuery();
}
/** @var \Drupal\search_api\Item\ItemInterface[] $items */
foreach ($items as $id => $item) {
$language_id = $item
->getLanguage();
$field_names = $this
->getLanguageSpecificSolrFieldNames($language_id, $index);
/** @var \Solarium\QueryType\Update\Query\Document $doc */
$doc = $update_query
->createDocument();
$doc
->setField('timestamp', $request_time);
$doc
->setField('id', $this
->createId($site_hash, $index_id, $id));
$doc
->setField('index_id', $index_id);
// Some processors might add an absolute boost factor to the item. Since
// Solr doesn't support index time boosting anymore, we simply store that
// factor and include it in the boost calculation at query time.
// @see \Drupal\search_api\Plugin\search_api\processor\TypeBoost
$doc
->setField('boost_document', $item
->getBoost());
// Suggester context boolean filter queries have issues with special
// characters like '/' or ':' if not properly quoted (by solarium). We
// avoid that by reusing our field name encoding.
$doc
->addField('sm_context_tags', Utility::encodeSolrName('search_api/index:' . $index_id));
// Add the site hash and language-specific base URL.
$doc
->setField('hash', $site_hash);
$doc
->addField('sm_context_tags', Utility::encodeSolrName('search_api_solr/site_hash:' . $site_hash));
$doc
->addField('sm_context_tags', Utility::encodeSolrName('drupal/langcode:' . $language_id));
if (!isset($base_urls[$language_id])) {
$url_options = [
'absolute' => TRUE,
];
if (isset($languages[$language_id])) {
$url_options['language'] = $languages[$language_id];
}
// An exception is thrown if this is called during a non-HTML response
// like REST or a redirect without collecting metadata. Avoid that by
// collecting and discarding it.
// See https://www.drupal.org/node/2638686.
$base_urls[$language_id] = Url::fromRoute('<front>', [], $url_options)
->toString(TRUE)
->getGeneratedUrl();
}
$doc
->setField('site', $base_urls[$language_id]);
$item_fields = $item
->getFields();
$item_fields += $special_fields = $this
->getSpecialFields($index, $item);
/** @var \Drupal\search_api\Item\FieldInterface $field */
foreach ($item_fields as $name => $field) {
// If the field is not known for the index, something weird has
// happened. We refuse to index the items and hope that the others are
// OK.
if (!isset($field_names[$name])) {
$vars = [
'%field' => $name,
'@id' => $id,
];
$this
->getLogger()
->warning('Error while indexing: Unknown field %field on the item with ID @id.', $vars);
$doc = NULL;
break;
}
$first_value = $this
->addIndexField($doc, $field_names[$name], $field
->getValues(), $field
->getType());
// Enable sorts in some special cases.
if ($first_value && !array_key_exists($name, $special_fields)) {
if (strpos($field_names[$name], 't') === 0 && strpos($field_names[$name], 'twm_suggest') !== 0 || strpos($field_names[$name], 's') === 0 && strpos($field_names[$name], 'spellcheck') !== 0) {
// Truncate the string to avoid Solr string field limitation.
// @see https://www.drupal.org/node/2809429
// @see https://www.drupal.org/node/2852606
// 128 characters should be enough for sorting and it makes no
// sense to heavily increase the index size. The DB backend limits
// the sort strings to 32 characters. But for example a
// search_api_id quickly exceeds 32 characters and the interesting
// ID is at the end of the string:
// 'entity:entity_test_mulrev_changed/2:en'.
if (mb_strlen($first_value) > 128) {
$first_value = Unicode::truncate($first_value, 128);
}
// Always copy fulltext and string fields to a dedicated sort fields
// for faster sorts and language specific collations. To allow
// sorted multilingual searches we need to fill *all*
// language-specific sort fields!
$sort_languages = array_keys(\Drupal::languageManager()
->getLanguages());
$sort_languages[] = LanguageInterface::LANGCODE_NOT_SPECIFIED;
foreach ($sort_languages as $sort_language_id) {
$key = Utility::encodeSolrName('sort' . SolrBackendInterface::SEARCH_API_SOLR_LANGUAGE_SEPARATOR . $sort_language_id . '_' . $name);
if (!$doc->{$key}) {
$doc
->addField($key, $first_value);
}
}
}
elseif (preg_match('/^([a-z]+)m(_.*)/', $field_names[$name], $matches) && strpos($field_names[$name], 'random_') !== 0) {
$key = $matches[1] . 's' . $matches[2];
if (!$doc->{$key}) {
// For other multi-valued fields (which aren't sortable by nature)
// we use the same hackish workaround like the DB backend: just
// copy the first value in a single value field for sorting.
$doc
->addField($key, $first_value);
}
}
}
}
if ($doc) {
$documents[] = $doc;
}
}
// Let other modules alter documents before sending them to solr.
$this->moduleHandler
->alter('search_api_solr_documents', $documents, $index, $items);
return $documents;
}