Elasticsearch多条件过滤数组元素的查询需求(5.6.11版本)
问题描述
每个文档包含如下数组字段:
"idList": [ 'DCCA7703Orange shirt', 'EFBA6705Blue bag', 'O7BA6405Blue socks' ]
需要编写Elasticsearch查询语句,仅获取idList数组中至少一个元素同时满足两个条件的文档:
- 元素以指定参数开头(例如
EFBA6705) - 元素包含另一个指定参数(例如
bag)
示例场景:
- 参数为
EFBA6705和bag时,上述文档会被命中(EFBA6705Blue bag同时满足两个条件) - 参数为
EFBA6705和socks时,文档不会被命中(两个参数分属不同数组元素)
已知限制:
idList字段映射为text类型,无法修改为nested或其他类型,映射详情:
"idList": { "type": "text", "fields": { "keyword": { "type": "keyword", "ignore_above": 256 } } }
- 使用的Elasticsearch版本为5.6.11
解决方案
由于idList.text会对数组元素分词,直接查询可能出现跨元素匹配的问题,因此必须借助idList.keyword字段(保留数组元素的完整字符串,不分词)来实现单元素的精确匹配。
查询语句示例(参数:EFBA6705 + bag)
{ "query": { "bool": { "must": [ { "wildcard": { "idList.keyword": "EFBA6705*bag*" } } ] } } }
逻辑说明
- 选择
idList.keyword字段:确保每个数组元素作为完整字符串被匹配,避免跨元素的分词匹配 wildcard模式EFBA6705*bag*:精准匹配所有以EFBA6705开头且包含bag的完整数组元素bool.must约束:只有当数组中存在至少一个元素满足上述模式时,文档才会被返回
通用用法
动态替换参数时,只需将wildcard的模式修改为{前缀参数}*{包含参数}*即可。
注意:ES5.6中,wildcard查询在keyword字段上的性能表现稳定,建议使用较长的前缀参数以避免过泛的匹配,提升查询效率。
内容的提问来源于stack exchange,提问作者Leonardo
相关产品推荐
相关产品推荐

