You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Shopware6对接Elasticsearch:精准搜索逻辑调整需求

解决Shopware6 + Elasticsearch精确子串搜索问题

针对你遇到的搜索ABC123返回无关关联结果的问题,核心是要让Elasticsearch只匹配包含该精确连续字符串的文档,而非拆分后的词项或模糊匹配结果。以下是具体落地步骤:

1. 先排查分词逻辑

首先确认Elasticsearch对搜索词的分词结果,避免因分词拆分导致的关联匹配。用Elasticsearch的_analyze API测试:

GET /_analyze
{
  "analyzer": "standard",
  "text": "ABC123"
}

如果返回的token是["abc123"],说明分词器未拆分该字符串,问题出在Shopware的查询逻辑;如果拆分成了["abc", "123"],则需要调整字段的分析器配置。

2. 替换Shopware默认搜索查询

Shopware默认的搜索会使用match查询(支持模糊匹配和多词OR逻辑),你需要通过自定义插件监听搜索事件,替换为精确匹配的查询逻辑:

方法1:使用短语匹配(Match Phrase)

短语匹配会严格匹配连续的字符串序列,适合你的需求。编写事件监听器:

use Shopware\Core\Content\Product\Search\ProductSearchCriteriaEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

class ExactProductSearchSubscriber implements EventSubscriberInterface
{
    public static function getSubscribedEvents(): array
    {
        return [
            ProductSearchCriteriaEvent::class => 'adjustProductSearch',
        ];
    }

    public function adjustProductSearch(ProductSearchCriteriaEvent $event): void
    {
        $searchTerm = $event->getSearchTerm();
        if (empty($searchTerm)) return;

        // 移除Shopware默认的搜索过滤器
        $criteria = $event->getCriteria();
        $criteria->removeFilter('search');

        // 添加短语匹配过滤器,覆盖名称、SKU等核心字段
        $criteria->addFilter(new \Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\MultiFilter(
            \Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\MultiFilter::CONNECTION_OR,
            [
                new \Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\MatchFilter(
                    'product.name',
                    $searchTerm,
                    ['operator' => 'phrase']
                ),
                new \Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\MatchFilter(
                    'product.sku',
                    $searchTerm,
                    ['operator' => 'phrase']
                ),
                // 按需添加其他需要匹配的字段,如description、customFields等
            ]
        ));
    }
}

方法2:使用Keyword字段的Wildcard查询

如果需要更严格的精确子串匹配(区分大小写等),可以用字段的keyword子字段做Wildcard查询(注意:开头带*的Wildcard会影响性能,适合数据量不大的场景):

// 替换上述MultiFilter内的规则为:
new \Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\WildcardFilter(
    'product.name.keyword',
    "*{$searchTerm}*"
),
new \Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\WildcardFilter(
    'product.sku.keyword',
    "*{$searchTerm}*"
)

3. 关闭模糊搜索

Shopware默认可能开启了模糊匹配(允许一定字符误差),导致返回类似ABC12、ABC124的结果。可以在MatchFilter中强制关闭:

new \Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\MatchFilter(
    'product.name',
    $searchTerm,
    [
        'operator' => 'phrase',
        'fuzziness' => 0 // 完全禁用模糊匹配
    ]
)

4. 自定义Elasticsearch字段映射(可选)

如果默认字段的分词器仍会拆分你的搜索词,可以自定义字段映射,添加一个不分词的子字段:
在Shopware自定义插件的Resources/config/elasticsearch/product.json中添加:

{
  "properties": {
    "name": {
      "type": "text",
      "fields": {
        "exact": {
          "type": "text",
          "analyzer": "keyword"
        }
      }
    }
  }
}

之后重建Elasticsearch索引,即可用product.name.exact字段进行精确匹配查询。

内容的提问来源于stack exchange,提问作者Ole Dahl Mansfeld

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 14:53:19