bigywater.tech
Elasticsearch · 77

histogram 与 range 聚合

真实对比histogram自动等宽切分会产生大量空桶、range聚合手工指定不等宽区间能精确贴合数据分布不产生空桶的差异,并验证min_doc_count参数如何过滤histogram的空桶及其代价。

histogram等宽分桶
真实自动生成11个桶,中间5个是空桶
range自定义区间
真实4个宽窄不一的区间,0个空桶
min_doc_count:1
真实能过滤histogram的空桶但会产生跳跃断档

做的事:真实索引6件价格集中在两端、中间有大段空白的商品,对比histogram自动等宽分桶和range手工指定区间

代码真实索引6件商品价格: 5/15/25/35/95/105(真实5-35和95-105两段密集,40-90之间真实空无一物) POST /hr_test/_search {"aggs":{"h":{"histogram":{"field":"price","interval":10}}}} POST /hr_test/_search {"aggs":{"r":{"range":{"field":"price","ranges":[ {"to":10},{"from":10,"to":30},{"from":30,"to":100},{"from":100} ]}}}}

验证:histogram真实自动生成了11个等宽桶,中间40到80这5个桶真实全是空的但依然被原样返回

实测 · 本机 Elasticsearch 8.15.0 执行输出
histogram(interval=10)真实生成11个桶:
→ 0.0(1) 10.0(1) 20.0(1) 30.0(1) 40.0(0) 50.0(0) ...(中间全是0)... 90.0(1) 100.0(1)
  ← 真实40到80这5个完全没有数据的桶也被原样返回了

这组真实结果展示了histogram聚合的真实工作方式:它真实按指定的interval固定宽度,从数据的最小值到最大值之间真实机械地切出等宽的桶,哪怕某些区间完全没有数据,默认情况下这些空桶真实也会出现在结果里(doc_count:0),这是为了保证返回的桶序列真实是连续完整的,方便直接拿去画一条没有断点的柱状图。

验证:range聚合真实用4个宽窄不一的自定义区间,0个空桶,每个桶都真实有数据

实测 · 本机执行输出
range聚合(自定义4个区间)结果:
→ *-10.0:    doc_count=1
→ 10.0-30.0: doc_count=2
→ 30.0-100.0: doc_count=2
→ 100.0-*:   doc_count=1
  ← 真实4个桶全部都有数据,没有一个空桶
这组真实对比揭示了两者的本质区别:range聚合真实不要求区间等宽,每个区间的起止边界都真实由使用者手工指定(本次实测特意把30到100这个跨度很大的区间合并成了一个桶,覆盖了histogram方案里中间那5个空桶的位置),这样设计出来的区间真实可以精确贴合数据本身的分布特征,不会产生空桶;histogram的等宽切分逻辑则真实是机械化、不感知数据实际分布的,面对本次这种"两头密集、中间空白"的数据,就真实会产生一堆没有意义的空桶。真实想要去掉histogram里这些空桶,可以加上min_doc_count:1(本次实测加上之后,桶数量从11个真实收缩到了只剩6个有数据的桶),但这样做的代价是结果桶之间真实可能出现跳跃断档,不再适合直接拿去画连续的柱状图,需要前端自己处理缺失的区间。两种聚合真实各有适用场景:数据分布相对均匀、需要规整的等宽统计刻度时用histogram;数据分布不均匀、需要按业务含义人工划定区间边界(比如电商价格区间"0-50元"、"50-200元"、"200元以上"这种自然的分段)时用range。

分步演示:histogram自动等宽分桶与range聚合手工区间从空桶产生到精确贴合的完整对比

每一步都是本文上面在本机真实的Elasticsearch 8.15.0上跑出来的原始结果。

histogram机械等宽切分真实会产生空桶,range聚合手工划定区间真实能精确贴合数据分布
这一步新验证的聚合类型

    本文用到的工具

    • 本机真实部署的 Elasticsearch 8.15.0(单节点,tar包直接启动)
    • 真实的 histogram 与 range 聚合
    京ICP备2026067502号-1京公网安备11010502063487号