Created
November 25, 2021 13:51
-
-
Save JEreth/dd415dfc796fb6a3782f38cab022e607 to your computer and use it in GitHub Desktop.
Magento2 Change elastic search query default operator to AND. See https://magento.stackexchange.com/questions/192718/how-do-i-change-magento-2-search-from-or-logic-to-and for full discussion.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?xml version="1.0"?> | |
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"> | |
<preference for="Magento\Elasticsearch\SearchAdapter\Query\Builder\Match" | |
type="<VENDOR>\<MODULE>\SearchAdapter\Query\Builder\Match" /> | |
</config> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
namespace <VENDOR>\<MODULE>\SearchAdapter\Query\Builder; | |
use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\AttributeProvider; | |
use Magento\Elasticsearch\Model\Adapter\FieldMapper\Product\FieldProvider\FieldType\ResolverInterface as TypeResolver; | |
use Magento\Elasticsearch\Model\Config; | |
use Magento\Elasticsearch\SearchAdapter\Query\ValueTransformerPool; | |
use Magento\Framework\Search\Request\Query\BoolExpression; | |
use Magento\Framework\Search\Request\QueryInterface as RequestQueryInterface; | |
use Magento\Elasticsearch\Model\Adapter\FieldMapperInterface; | |
use Magento\Framework\Search\Adapter\Preprocessor\PreprocessorInterface; | |
/** | |
* Extend Builder for match query. | |
* See https://magento.stackexchange.com/questions/192718/how-do-i-change-magento-2-search-from-or-logic-to-and for the full discussuon | |
*/ | |
class Match extends \Magento\Elasticsearch\SearchAdapter\Query\Builder\Match | |
{ | |
/** | |
* Elasticsearch condition for case when query must not appear in the matching documents. | |
*/ | |
const QUERY_CONDITION_MUST_NOT = 'must_not'; | |
/** | |
* @var FieldMapperInterface | |
*/ | |
private $fieldMapper; | |
/** | |
* @var AttributeProvider | |
*/ | |
private $attributeProvider; | |
/** | |
* @var TypeResolver | |
*/ | |
private $fieldTypeResolver; | |
/** | |
* @var ValueTransformerPool | |
*/ | |
private $valueTransformerPool; | |
/** | |
* @var Config | |
*/ | |
private $config; | |
/** | |
* @param FieldMapperInterface $fieldMapper | |
* @param AttributeProvider $attributeProvider | |
* @param TypeResolver $fieldTypeResolver | |
* @param ValueTransformerPool $valueTransformerPool | |
* @param Config $config | |
*/ | |
public function __construct( | |
FieldMapperInterface $fieldMapper, | |
AttributeProvider $attributeProvider, | |
TypeResolver $fieldTypeResolver, | |
ValueTransformerPool $valueTransformerPool, | |
Config $config | |
) { | |
$this->fieldMapper = $fieldMapper; | |
$this->attributeProvider = $attributeProvider; | |
$this->fieldTypeResolver = $fieldTypeResolver; | |
$this->valueTransformerPool = $valueTransformerPool; | |
$this->config = $config; | |
parent::__construct($fieldMapper, $attributeProvider, $fieldTypeResolver, $valueTransformerPool, $config); | |
} | |
/** | |
* Creates valid ElasticSearch search conditions from Match queries. | |
* | |
* The purpose of this method is to create a structure which represents valid search query | |
* for a full-text search. | |
* It sets search query condition, the search query itself, and sets the search query boost. | |
* | |
* The search query boost is an optional in the search query and therefore it will be set to 1 by default | |
* if none passed with a match query. | |
* | |
* @param array $matches | |
* @param array $queryValue | |
* @return array | |
*/ | |
protected function buildQueries(array $matches, array $queryValue) | |
{ | |
$conditions = []; | |
// Checking for quoted phrase \"phrase test\", trim escaped surrounding quotes if found | |
$count = 0; | |
$value = preg_replace('#^"(.*)"$#m', '$1', $queryValue['value'], -1, $count); | |
$condition = ($count) ? 'match_phrase' : 'match'; | |
$transformedTypes = []; | |
foreach ($matches as $match) { | |
$resolvedField = $this->fieldMapper->getFieldName( | |
$match['field'], | |
['type' => FieldMapperInterface::TYPE_QUERY] | |
); | |
$attributeAdapter = $this->attributeProvider->getByAttributeCode($resolvedField); | |
$fieldType = $this->fieldTypeResolver->getFieldType($attributeAdapter); | |
$valueTransformer = $this->valueTransformerPool->get($fieldType ?? 'text'); | |
$valueTransformerHash = \spl_object_hash($valueTransformer); | |
if (!isset($transformedTypes[$valueTransformerHash])) { | |
$transformedTypes[$valueTransformerHash] = $valueTransformer->transform($value); | |
} | |
$transformedValue = $transformedTypes[$valueTransformerHash]; | |
if (null === $transformedValue) { | |
//Value is incompatible with this field type. | |
continue; | |
} | |
$matchCondition = $match['matchCondition'] ?? $condition; | |
if($matchCondition != 'match_phrase_prefix'){ | |
$field = [ | |
'query' => $transformedValue, | |
'boost' => $match['boost'] ?? 1, | |
'operator' => 'and' | |
]; | |
} else { | |
$field = [ | |
'query' => $transformedValue, | |
'boost' => $match['boost'] ?? 1 | |
]; | |
} | |
$conditions[] = [ | |
'condition' => $queryValue['condition'], | |
'body' => [ | |
$matchCondition => [ | |
$resolvedField => $field, | |
], | |
], | |
]; | |
} | |
return $conditions; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment