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

Laravel中Elasticsearch如何实现字符串精确包含匹配查询

实现Elasticsearch类似SQL LIKE '%query%'的精确包含匹配

你当前使用phrase_prefix类型的multi_match查询,逻辑是匹配以查询短语为前缀的连续词序列,和SQL中LIKE '%query%'(任意位置包含子串)的逻辑完全不同,所以无法得到期望结果。可以通过以下两种方式解决:

方案1:快速调整查询逻辑(无需修改索引映射)

使用query_string查询,支持通配符*来模拟LIKE的模糊匹配效果:

public function searchAdverts(string $query)
{
    $params = [
        'index' => 'adverts',
        'body' => [
            'query' => [
                'query_string' => [
                    'query'  => "*{$query}*",
                    'fields' => ['title', 'content']
                ]
            ]
        ]
    ];
    $response = $this->client->search($params);
    return $response;
}

注意:这种方式适合临时需求,如果查询词过短(1-2个字符),会因为需要遍历大量分词结果导致性能下降。

方案2:优化索引映射(高效长期方案)

默认的text字段会被分词器拆分,无法高效匹配任意子串。可以给title和content添加keyword类型的子字段,同时保留原字段的全文检索能力:

修改后的索引映射

'index' => 'adverts',
'body' => [
    'mappings' => [
        'properties' => [
            'id' => ['type' => 'integer'],
            'title' => [
                'type' => 'text',
                'fields' => [
                    'keyword' => [
                        'type' => 'keyword',
                        'ignore_above' => 256 // 根据实际内容长度调整
                    ]
                ]
            ],
            'content' => [
                'type' => 'text',
                'fields' => [
                    'keyword' => [
                        'type' => 'keyword',
                        'ignore_above' => 1024
                    ]
                ]
            ],
        ]
    ],
]

注意:修改映射后需要重新索引所有数据,新映射才会生效。

对应的查询代码

使用wildcard查询针对keyword子字段,实现和LIKE '%query%'完全一致的逻辑,且性能更优:

public function searchAdverts(string $query)
{
    $params = [
        'index' => 'adverts',
        'body' => [
            'query' => [
                'bool' => [
                    'should' => [
                        [
                            'wildcard' => [
                                'title.keyword' => "*{$query}*"
                            ]
                        ],
                        [
                            'wildcard' => [
                                'content.keyword' => "*{$query}*"
                            ]
                        ]
                    ]
                ]
            ]
        ]
    ];
    $response = $this->client->search($params);
    return $response;
}

内容的提问来源于stack exchange,提问作者Dmitrijs

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 03:16:04