diff --git a/vendor/magento/module-catalog-search/Model/Search/ReaderPlugin.php b/vendor/magento/module-catalog-search/Model/Search/ReaderPlugin.php index 2f6a402b204..4adb9c2299e 100644 --- a/vendor/magento/module-catalog-search/Model/Search/ReaderPlugin.php +++ b/vendor/magento/module-catalog-search/Model/Search/ReaderPlugin.php @@ -5,6 +5,9 @@ */ namespace Magento\CatalogSearch\Model\Search; +use Magento\CatalogSearch\Model\Search\Request\ModifierInterface; +use Magento\Framework\Config\ReaderInterface; + /** * @deprecated 101.0.0 * @see \Magento\ElasticSearch @@ -12,34 +15,34 @@ namespace Magento\CatalogSearch\Model\Search; class ReaderPlugin { /** - * @var \Magento\CatalogSearch\Model\Search\RequestGenerator + * @var ModifierInterface */ - private $requestGenerator; + private $requestModifier; /** - * @param \Magento\CatalogSearch\Model\Search\RequestGenerator $requestGenerator + * @param ModifierInterface $requestModifier */ public function __construct( - \Magento\CatalogSearch\Model\Search\RequestGenerator $requestGenerator + ModifierInterface $requestModifier ) { - $this->requestGenerator = $requestGenerator; + $this->requestModifier = $requestModifier; } /** * Merge reader's value with generated * - * @param \Magento\Framework\Config\ReaderInterface $subject + * @param ReaderInterface $subject * @param array $result * @param string|null $scope * @return array * @SuppressWarnings(PHPMD.UnusedFormalParameter) */ public function afterRead( - \Magento\Framework\Config\ReaderInterface $subject, + ReaderInterface $subject, array $result, $scope = null ) { - $result = array_merge_recursive($result, $this->requestGenerator->generate()); + $result = $this->requestModifier->modify($result); return $result; } } diff --git a/vendor/magento/module-catalog-search/Model/Search/Request/MatchQueriesModifier.php b/vendor/magento/module-catalog-search/Model/Search/Request/MatchQueriesModifier.php new file mode 100644 index 00000000000..8d1675884c3 --- /dev/null +++ b/vendor/magento/module-catalog-search/Model/Search/Request/MatchQueriesModifier.php @@ -0,0 +1,62 @@ +queries = $queries; + } + + /** + * @inheritdoc + */ + public function modify(array $requests): array + { + foreach ($requests as &$request) { + foreach ($this->queries as $query => $fields) { + if (!empty($request[self::NODE_QUERIES][$query][self::NODE_MATCH])) { + foreach ($request[self::NODE_QUERIES][$query][self::NODE_MATCH] as $index => $match) { + $field = $match[self::NODE_MATCH_ATTRIBUTE_FIELD] ?? null; + if ($field !== null && isset($fields[$field])) { + $request[self::NODE_QUERIES][$query][self::NODE_MATCH][$index] += $fields[$field]; + } + } + } + } + } + return $requests; + } +} diff --git a/vendor/magento/module-catalog-search/Model/Search/Request/ModifierComposite.php b/vendor/magento/module-catalog-search/Model/Search/Request/ModifierComposite.php new file mode 100644 index 00000000000..6290b5bd7ce --- /dev/null +++ b/vendor/magento/module-catalog-search/Model/Search/Request/ModifierComposite.php @@ -0,0 +1,46 @@ +modifiers = $modifiers; + } + + /** + * @inheritdoc + */ + public function modify(array $requests): array + { + foreach ($this->modifiers as $modifier) { + $requests = $modifier->modify($requests); + } + return $requests; + } +} diff --git a/vendor/magento/module-catalog-search/Model/Search/Request/ModifierInterface.php b/vendor/magento/module-catalog-search/Model/Search/Request/ModifierInterface.php new file mode 100644 index 00000000000..68421d6cb1d --- /dev/null +++ b/vendor/magento/module-catalog-search/Model/Search/Request/ModifierInterface.php @@ -0,0 +1,22 @@ +collectionFactory = $collectionFactory; + } + + /** + * @inheritdoc + */ + public function modify(array $requests): array + { + $attributes = $this->getSearchableAttributes(); + foreach ($requests as $code => $request) { + $matches = $request['queries']['partial_search']['match'] ?? []; + if ($matches) { + foreach ($matches as $index => $match) { + $field = $match['field'] ?? null; + if ($field && $field !== '*' && !isset($attributes[$field])) { + unset($matches[$index]); + } + } + $requests[$code]['queries']['partial_search']['match'] = array_values($matches); + } + } + return $requests; + } + + /** + * Retrieve searchable attributes + * + * @return Attribute[] + */ + private function getSearchableAttributes(): array + { + $attributes = []; + /** @var Collection $collection */ + $collection = $this->collectionFactory->create(); + $collection->addFieldToFilter( + ['is_searchable', 'is_visible_in_advanced_search', 'is_filterable', 'is_filterable_in_search'], + [1, 1, [1, 2], 1] + ); + + /** @var Attribute $attribute */ + foreach ($collection->getItems() as $attribute) { + $attributes[$attribute->getAttributeCode()] = $attribute; + } + + return $attributes; + } +} diff --git a/vendor/magento/module-catalog-search/Model/Search/Request/SearchModifier.php b/vendor/magento/module-catalog-search/Model/Search/Request/SearchModifier.php new file mode 100644 index 00000000000..54082dd28ec --- /dev/null +++ b/vendor/magento/module-catalog-search/Model/Search/Request/SearchModifier.php @@ -0,0 +1,39 @@ +requestGenerator = $requestGenerator; + } + + /** + * @inheritdoc + */ + public function modify(array $requests): array + { + $requests = array_merge_recursive($requests, $this->requestGenerator->generate()); + return $requests; + } +} diff --git a/vendor/magento/module-catalog-search/etc/di.xml b/vendor/magento/module-catalog-search/etc/di.xml index 6ff9119e78c..cf0ca6319a6 100644 --- a/vendor/magento/module-catalog-search/etc/di.xml +++ b/vendor/magento/module-catalog-search/etc/di.xml @@ -14,6 +14,7 @@ + @@ -244,4 +245,27 @@ + + + + Magento\CatalogSearch\Model\Search\Request\SearchModifier + Magento\CatalogSearch\Model\Search\Request\PartialSearchModifier + Magento\CatalogSearch\Model\Search\Request\MatchQueriesModifier + + + + + + + + + prefix_search + + + sku_prefix_search + + + + + diff --git a/vendor/magento/module-elasticsearch/Model/Adapter/Index/Builder.php b/vendor/magento/module-elasticsearch/Model/Adapter/Index/Builder.php index 1cad781ad6d..f5a70d2d095 100644 --- a/vendor/magento/module-elasticsearch/Model/Adapter/Index/Builder.php +++ b/vendor/magento/module-elasticsearch/Model/Adapter/Index/Builder.php @@ -63,6 +63,15 @@ class Builder implements BuilderInterface ), 'char_filter' => array_keys($charFilter) ], + // this analyzer must not include stemmer filter + 'prefix_search' => [ + 'type' => 'custom', + 'tokenizer' => key($tokenizer), + 'filter' => array_merge( + ['lowercase', 'keyword_repeat'] + ), + 'char_filter' => array_keys($charFilter) + ], 'sku' => [ 'type' => 'custom', 'tokenizer' => 'keyword', @@ -70,6 +79,14 @@ class Builder implements BuilderInterface ['lowercase', 'keyword_repeat'], array_keys($filter) ), + ], + // this analyzer must not include stemmer filter + 'sku_prefix_search' => [ + 'type' => 'custom', + 'tokenizer' => 'keyword', + 'filter' => array_merge( + ['lowercase', 'keyword_repeat'] + ), ] ], 'tokenizer' => $tokenizer, diff --git a/vendor/magento/module-elasticsearch/SearchAdapter/Query/Builder/Match.php b/vendor/magento/module-elasticsearch/SearchAdapter/Query/Builder/Match.php index ac40e4ee3c0..b4ed33fb85f 100644 --- a/vendor/magento/module-elasticsearch/SearchAdapter/Query/Builder/Match.php +++ b/vendor/magento/module-elasticsearch/SearchAdapter/Query/Builder/Match.php @@ -154,15 +154,18 @@ class Match implements QueryInterface continue; } $matchCondition = $match['matchCondition'] ?? $condition; + $fields = []; + $fields[$resolvedField] = [ + 'query' => $transformedValue, + 'boost' => $match['boost'] ?? 1, + ]; + if (isset($match['analyzer'])) { + $fields[$resolvedField]['analyzer'] = $match['analyzer']; + } $conditions[] = [ 'condition' => $queryValue['condition'], 'body' => [ - $matchCondition => [ - $resolvedField => [ - 'query' => $transformedValue, - 'boost' => $match['boost'] ?? 1, - ], - ], + $matchCondition => $fields, ], ]; }