管道聚合是干什么的
管道聚合不产生新的桶,而是对已有桶或指标做第二次计算:derivative 求相邻桶差分,cumulative_sum 做累计求和,moving_fn 做移动窗口计算,bucket_script 对桶内多个指标做算术,bucket_sort 对桶排序并截断。它们通过 buckets_path 引用同层或上层聚合的名称,路径写错会直接报无法解析。
基本信息
| 常见类型 | derivative / cumulative_sum / moving_fn / bucket_script / bucket_sort |
|---|---|
| 连接方式 | buckets_path 指向聚合名称,用 > 表示跨层级 |
| 缺口处理 | gap_policy 取 skip(默认)或 insert_zeros |
| 依赖 | 必须先有指标聚合或桶聚合作为输入 |
| 版本差异 | ES 6.x 起提供,新增类型与参数随版本演进 |
示例
示例
GET /sales/_search
{
"size": 0,
"aggs": {
"per_month": {
"date_histogram": { "field": "date", "calendar_interval": "month" },
"aggs": {
"sales": { "sum": { "field": "amount" } },
"sales_diff": { "derivative": { "buckets_path": "sales" } },
"sales_cum": { "cumulative_sum": { "buckets_path": "sales" } }
}
}
}
}典型使用场景
- 环比分析:derivative 求相邻周期差值,直接得到增量
- 累计曲线:cumulative_sum 做年度累计金额
- 趋势平滑:moving_fn 做移动平均,压低单点波动
- 桶内占比:bucket_script 用除法算比例、转化率
- 排行榜:bucket_sort 按指标排序并只保留前 N 个桶
常见管道聚合对照
| 类型 | 输入 | 输出与注意 |
|---|---|---|
| derivative | 单个指标路径 | 相邻桶差值,首个桶无前值返回空 |
| cumulative_sum | 单个指标路径 | 累计值,受 gap_policy 影响 |
| bucket_script | 多个指标路径 | 按脚本做算术,分母为 0 需判断 |
| bucket_sort | 排序字段与 from/size | 对父桶排序截断,会改变返回的桶集合 |
buckets_path 用 > 表示跨层级,如 "agg1>agg2",同层直接用聚合名。路径写错或指向不存在的聚合会抛无法解析路径的错误,报错信息不会给出正确写法。
管道聚合只能引用兄弟层或父层的聚合结果,不能引用子聚合;把管道聚合写在桶内部却去引用外层同名指标,是最常见的层级错误。
为什么需要第二次计算
业务问题常常不是一次聚合能直接回答的:要环比就得拿本次结果与上一次比,要占比就得拿子项除以合计,要累计就得把每个窗口依次累加。这些运算的对象是聚合出来的数值而不是原始文档,所以只能在聚合结果之上再算一层。管道聚合就是这一层,它不改变分桶方式,只对已有桶与指标做变换,因此额外的性能开销主要来自父聚合本身。
管道聚合产出的是派生值,不会改变原始桶的文档计数;核对口径时以父聚合的 doc_count 为基准,不要拿派生值反推样本量。