Elasticsearch如何将文档按是否存在extra_data.legend字段分桶
Elasticsearch按字段存在性分桶的实现方案
不需要使用terms聚合,也不需要额外开发补集聚合,以下两种方案都可以直接实现需求:
方案1:filters聚合(最推荐)
直接在filters中定义两个互斥的过滤规则,一次查询即可返回两个分桶的结果,后续扩展子聚合也更方便,完全不依赖字段类型:
GET /你的索引名/_search { "size": 0, // 不需要返回原始文档可设为0,需要返回则调整为对应数值 "aggs": { "legend_field_bucket": { "filters": { "filters": { "包含extra_data.legend字段": { "exists": { "field": "extra_data.legend" } }, "不存在extra_data.legend字段": { "bool": { "must_not": [ { "exists": { "field": "extra_data.legend" } } ] } } } } // 如需获取分桶内的具体文档,可添加top_hits子聚合 /*, "aggs": { "bucket_docs": { "top_hits": { "size": 10 } } } */ } } }
方案2:exists + missing聚合组合
你提到的missing聚合确实只有单桶,它对应的补集就是exists聚合,二者可以放在同一层级同时执行,同样可以得到两类分桶的结果:
GET /你的索引名/_search { "size": 0, "aggs": { "包含extra_data.legend字段": { "exists": { "field": "extra_data.legend" } }, "不存在extra_data.legend字段": { "missing": { "field": "extra_data.legend" } } } }
注意事项
- 两种方案都不限制
extra_data.legend的字段类型,text类型字段也可以正常运行,不存在terms聚合的基数过高问题 - 如果业务规则中需要把字段值为空字符串、空数组的情况归为「不存在」分类,只需要在过滤条件中补充对应判断逻辑即可
内容的提问来源于stack exchange,提问作者ericjardon
相关产品推荐
相关产品推荐

