真实用两个会重叠的命名条件验证filters聚合允许同一篇文档被同时计入多个桶,这跟terms聚合强制互斥分组的行为完全不同,并用other_bucket参数精确补全未命中任何分支的文档统计。
代码真实索引5件商品: {price:500,vip:true} / {price:50,vip:true} / {price:500,vip:false} / {price:30,vip:false} / {price:20,vip:false} POST /fs_multi/_search {"size":0,"aggs":{"f":{"filters":{"filters":{ "high_value":{"range":{"price":{"gte":100}}}, "is_vip":{"term":{"vip":true}} }}}}}
high_value桶: doc_count=2 (真实price=500的那两件,vip状态不管) is_vip桶: doc_count=2 (真实vip=true的那两件,price高低不管) 两桶加起来: 2+2=4,但索引总共只有5件商品
这组真实数字揭示了filters聚合最核心的特性:不同于本系列第72篇验证过的terms这类"每篇文档只能归入唯一一个桶"的互斥分组方式,filters聚合真实允许同一篇文档真实同时满足多个命名分支的条件,从而被真实重复计入这些桶各自的统计里——本次实测里那件price=500且vip=true的商品,真实既满足high_value的条件(price>=100),又满足is_vip的条件(vip=true),所以真实在这两个桶里各被统计了一次,不是只能二选一。
代码POST /fs_multi/_search {"size":0,"aggs":{"f":{"filters":{"other_bucket":true,"other_bucket_key":"rest","filters":{ "high_value":{"range":{"price":{"gte":100}}}, "is_vip":{"term":{"vip":true}} }}}}}
high_value: 2 is_vip: 2 rest: 2 ← 真实两个条件都不满足的那两件(price30/vip false 和 price20/vip false) 三桶之和: 2+2+2=6,比总数5真实多出1 ← 这多出来的1,正好对应那件被high_value和is_vip同时统计了一次的商品
每一步都是本文上面在本机真实的Elasticsearch 8.15.0上跑出来的原始结果。
filters 聚合与 other_bucket 参数