跳转到内容

聚合与深分页

用途:用 ES 做统计与分组时避免“内存爆、数字不准”

类型 例子 说明
指标(Metrics) avg、sum、max、stats、percentiles、cardinality 计算数值
桶(Bucket) terms、date_histogram、range、histogram、filter、nested 分组
管道(Pipeline) derivative、cumulative_sum、bucket_sort、moving_avg 在桶结果之上二次计算
  1. terms 聚合是近似的:每个分片先取自己的 size × shard_size 再归并,跨分片长尾统计可能偏差。用 shard_size 调优,或明确“这是 Top-N 近似”。
  2. cardinality 是 HLL 估算:误差随基数增长(默认 precision_threshold 3000,上限 40000)。要求精确去重时用其他方案(数据库、位图、分组累加)。
  3. percentiles 基于 t-digest 近似:tdigest.compression 控制精度与内存。
  4. 缺失值与空桶:date_histogram 的 min_doc_count: 0 + extended_bounds 补齐时间轴;missing 参数处理字段缺失。

按用户 ID、订单号这类高基数字段分组会消耗大量内存与 CPU:

需求 方案
Top-N 大类别 terms + 合理 size,配合 include 过滤
全量分组统计 交给数仓/OLAP(ClickHouse、Doris 类),ES 只做检索与轻量聚合
精确去重计数 数据库或位图结构(RoaringBitmap 类)
多维下钻 预聚合汇总表,或列式 OLAP 引擎

经验边界:ES 适合“检索 + 有限维度聚合”,不适合当 OLAP 引擎用。

  • nested 聚合:对数组内对象保持关联统计(如“订单行按品类聚合”)。
  • reverse_nested:从子文档回到父文档维度统计。
  • 子文档聚合代价高,设计阶段就要判断是否真的需要 nested(很多场景可拆成独立索引 + 关联查询)。
  1. 聚合字段必须有 doc_values(列式正排),否则无法聚合。
  2. 先 filter 缩小文档集再聚合。
  3. 控制桶数量:嵌套桶乘积会爆炸(date_histogram × terms × range)。
  4. 用 execution_hint: map / composite 分页聚合处理大结果集(composite 支持游标翻页)。
  5. 避免在 text 字段上开 fielddata。
  6. 大聚合走独立节点/线程池,避免影响在线查询。
误区 修正
把 cardinality 当精确 UV 明确它是估算,或换方案
terms 聚合 size=10000 取全量 内存与延迟风险,用 composite 分页或离线计算
用 ES 做复杂多表关联分析 关联能力弱,交给 OLAP/数仓
聚合与检索混在一个慢查询里 拆分:检索列表 + 单独聚合请求(可缓存)
忽略时区 date_histogram 显式 time_zone,或统一 UTC 存储
  • Elasticsearch 官方文档:Aggregations、composite、Precision and recall of terms aggregator
  • 《Elasticsearch 权威指南》聚合章节