我正在尝试使用搜索同义词。我创建了一个同义词组,并添加了用逗号分隔的同义词,然后运行了完整的重新索引。
现在我正在使用以下 API 调用来测试它
http://website/rest/V1/products?searchCriteria[filter_groups][0][filters][0][field]=name&searchCriteria[filter_groups][0][filters][0][value]=%25cucumber%25&searchCriteria[filter_groups][0][filters][0][condition_type]=like&searchCriteria[pageSize]=5&searchCriteria[currentPage]=1
这是返回数据。但如果我用同义词替换“黄瓜”,则不会返回任何结果。 我使用开放搜索作为我的搜索引擎,我在
vendor/magento/module-open-search/etc/search_engine.xml
中找到了这段代码
<engines xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Search/etc/search_engine.xsd">
<engine name="opensearch">
<feature name="synonyms" support="true" />
</engine>
</engines>
我不确定我是否遗漏了什么或做错了什么。
由于我在网上找不到任何文章告诉我为什么搜索条件 api 不适用于同义词,因此我采取了解决方法。分享这是否对将来的任何人有帮助。 创建了我的自定义搜索 api。
/**
* Check if query string has synonyms set
*
* @param string $queryString
* @return array|bool
*/
private function checkForSynonyms($queryString,$processResponse = false)
{
$analyzedData = $synonyms = [];
/**
* @var \Magento\Search\Api\SynonymAnalyzerInterface
*/
$analyzedData = $this->synonymAnalyzerInterface->getSynonymsForPhrase($queryString);
foreach($analyzedData as $synm):
if(count($synm) > 1):
$synonyms = $synm;
endif;
endforeach;
return $processResponse ? $this->processSynonymResponse($queryString,$synonyms) : $synonyms ?? false;
}
/**
* Prepare synonyms for api call
*
* @param string $queryString
* @param array $synonyms
* @return array|bool
*/
private function processSynonymResponse($queryString,$synonyms = [])
{
$querySynm = null;
$searchStrings = [];
if($synonyms):
foreach($synonyms as $synonym) {
if(str_contains($queryString, $synonym))
$querySynm = $synonym;
}
foreach($synonyms as $synm) {
if($querySynm && $synm != $querySynm) {
$searchStrings[] = str_replace($querySynm, $synm, $queryString);
}
}
array_push($searchStrings, $queryString);
return $searchStrings;
endif;
return false;
}
在search api中调用上述函数,并添加同义词作为OR条件
$synonym = $this->checkForSynonyms(strtolower($queryString),true);
if($synonym):
foreach($synonym as $synmQuery):
$filters[] = $this->filterBuilder->setField('name')
->setValue('%'.$synmQuery.'%')
->setConditionType('like')->create();
endforeach;
foreach($filters as $filter) {
$this->filterGroupBuilder->addFilter($filter);
}
$filterGrpBuilder = $this->filterGroupBuilder->create();
$this->searchCriteriaBuilder->setFilterGroups([$filterGrpBuilder]);
else:
$this->searchCriteriaBuilder->addFilter('name', '%'.$queryString.'%', 'like');
endif;
我还没有在不同的场景下测试过这个,但这适用于我的情况。