ElasticSearch筛选数组字段包含全部指定值的文档 优化查询方案问询
方案1:不修改现有索引映射的简洁写法
你当前的多nested查询逻辑是完全正确的,只需简化掉冗余的嵌套bool结构即可,性能和原有写法一致:
{ "query": { "bool": { "filter": [ { "nested": { "path": "events", "query": { "term": { "events.type": "A" } } } }, { "nested": { "path": "events", "query": { "term": { "events.type": "B" } } } } ] } } }
该写法的逻辑是:要求文档中同时存在至少1个匹配A的嵌套文档、至少1个匹配B的嵌套文档,完全符合你的需求。
方案2:高频查询场景下的性能最优方案
如果你经常需要做这类「数组中同时存在多个值」的查询,建议新增冗余字段避免nested查询开销,性能可提升30%以上,写法也更简洁:
- 首先为索引新增
event_types冗余字段,类型为keyword数组:
PUT XXX/_mapping { "properties": { "event_types": { "type": "keyword" } } }
- 配置Ingest Pipeline自动填充冗余字段,无需修改业务写入逻辑:
PUT _ingest/pipeline/populate_event_types { "processors": [ { "script": { "source": "ctx.event_types = ctx.events.stream().map(e -> e.type).collect(Collectors.toList())" } } ] }
- 后续查询直接用普通term查询即可:
{ "query": { "bool": { "filter": [ { "term": { "event_types": "A" } }, { "term": { "event_types": "B" } } ] } } }
之前两种错误写法的原因说明
- nested查询内部用bool.should:nested查询的匹配粒度是单条嵌套文档,should只要同一条嵌套文档满足任意条件就命中,所以只会返回包含A或B的文档,无法要求同时存在两个不同的嵌套文档。
- match查询加AND运算符:AND逻辑要求同一个字段同时包含所有检索词,不存在单个嵌套文档的type同时为A和B,所以没有返回结果。
内容的提问来源于stack exchange,提问作者Lalaphoon
相关产品推荐
相关产品推荐

