Elasticsearch无需修改映射,如何实现含特殊字符精准搜索?
问题背景
你运行着Elasticsearch集群,索引采用动态映射,分词器为standard。通过Analyze API验证,some-data会被拆分为some和data两个独立词项。当前message字段映射如下:
"message": { "type": "text", "fields": { "keyword": { "type": "keyword", "ignore_above": 256 } } }
已索引4条文档:
data with some-data
data with some data
data
some
执行普通multi_match查询some-data返回全部4条结果;term查询message.keyword返回空(因keyword存储完整字段值,而非子串);phrase类型的multi_match返回包含some-data和some data的两条结果。你需要仅返回含some-data的文档,且不修改现有映射。
可行解决方案
1. 脚本查询(精准子串匹配)
通过脚本检查message.keyword的原始值是否包含目标子串,精准命中符合条件的文档:
GET index/_search { "query": { "bool": { "must": [ { "script": { "script": { "source": "doc['message.keyword'].value.contains(params.target)", "params": { "target": "some-data" } } } } ] } } }
2. Wildcard查询(简单直接)
利用通配符匹配message.keyword中包含some-data的子串,写法简洁但数据量大时,开头带*的通配符可能影响性能:
GET index/_search { "query": { "wildcard": { "message.keyword": "*some-data*" } } }
3. Query String查询(子串匹配)
指定message.keyword字段,通过引号包裹通配符查询词实现匹配:
GET index/_search { "query": { "query_string": { "default_field": "message.keyword", "query": "\"*some-data*\"" } } }
原理说明
message.keyword存储的是字段的原始完整文本(未经过分词处理),因此可以直接对原始内容进行子串匹配,从而区分some-data和some data两种不同的文本形式,无需修改现有映射。
内容的提问来源于stack exchange,提问作者Umang Pachaury
相关产品推荐
相关产品推荐

