管道聚合
编辑管道聚合编辑
管道聚合作用于其他聚合产生的输出,而不是文档集,向输出树添加信息。管道聚合有很多不同的类型,每种类型都从其他聚合中计算不同的信息,但这些类型可以分为两个类别
- 父级
- 一类管道聚合,它使用其父级聚合的输出,并能够计算新的桶或新的聚合以添加到现有桶中。
- 兄弟
- 管道聚合使用兄弟聚合的输出,并能够计算一个新的聚合,该聚合将与兄弟聚合位于同一级别。
管道聚合可以使用 buckets_path
参数引用它们执行计算所需的聚合,以指示所需指标的路径。定义这些路径的语法可以在下面的 buckets_path
语法 部分找到。
管道聚合不能有子聚合,但根据类型,它可以在 buckets_path
中引用另一个管道,允许管道聚合进行链式操作。例如,可以将两个导数链接在一起以计算二阶导数(即导数的导数)。
由于管道聚合只是添加到输出中,因此在链接管道聚合时,每个管道聚合的输出都将包含在最终输出中。
buckets_path
语法编辑
大多数管道聚合需要另一个聚合作为其输入。输入聚合通过 buckets_path
参数定义,该参数遵循特定格式
AGG_SEPARATOR = `>` ; METRIC_SEPARATOR = `.` ; AGG_NAME = <the name of the aggregation> ; METRIC = <the name of the metric (in case of multi-value metrics aggregation)> ; MULTIBUCKET_KEY = `[<KEY_NAME>]` PATH = <AGG_NAME><MULTIBUCKET_KEY>? (<AGG_SEPARATOR>, <AGG_NAME> )* ( <METRIC_SEPARATOR>, <METRIC> ) ;
例如,路径 "my_bucket>my_stats.avg"
将指向 "my_stats"
指标中的 avg
值,该指标包含在 "my_bucket"
桶聚合中。
以下是一些其他示例
-
multi_bucket["foo"]>single_bucket>multi_metric.avg
将指向"multi_bucket"
多桶聚合的"foo"
桶中,"single_bucket"
单桶内的"multi_metric"
聚合中的avg
指标。 -
agg1["foo"]._count
将获取多桶聚合"multi_bucket"
中"foo"
桶的_count
指标
路径相对于管道聚合的位置;它们不是绝对路径,并且路径不能返回到聚合树的“上层”。例如,此导数嵌入在 date_histogram 中,并引用“兄弟”指标 "the_sum"
response = client.search( body: { aggregations: { my_date_histo: { date_histogram: { field: 'timestamp', calendar_interval: 'day' }, aggregations: { the_sum: { sum: { field: 'lemmings' } }, the_deriv: { derivative: { buckets_path: 'the_sum' } } } } } } ) puts response
POST /_search { "aggs": { "my_date_histo": { "date_histogram": { "field": "timestamp", "calendar_interval": "day" }, "aggs": { "the_sum": { "sum": { "field": "lemmings" } }, "the_deriv": { "derivative": { "buckets_path": "the_sum" } } } } } }
buckets_path
也用于兄弟管道聚合,其中聚合位于一系列桶的“旁边”,而不是嵌入在“内部”。例如,max_bucket
聚合使用 buckets_path
来指定嵌入在兄弟聚合中的指标
response = client.search( body: { aggregations: { sales_per_month: { date_histogram: { field: 'date', calendar_interval: 'month' }, aggregations: { sales: { sum: { field: 'price' } } } }, max_monthly_sales: { max_bucket: { buckets_path: 'sales_per_month>sales' } } } } ) puts response
POST /_search { "aggs": { "sales_per_month": { "date_histogram": { "field": "date", "calendar_interval": "month" }, "aggs": { "sales": { "sum": { "field": "price" } } } }, "max_monthly_sales": { "max_bucket": { "buckets_path": "sales_per_month>sales" } } } }
如果兄弟管道聚合引用多桶聚合,例如 terms
聚合,它还可以选择从多桶中选择特定的键。例如,bucket_script
可以选择两个特定的桶(通过它们的桶键)来执行计算
response = client.search( body: { aggregations: { sales_per_month: { date_histogram: { field: 'date', calendar_interval: 'month' }, aggregations: { sale_type: { terms: { field: 'type' }, aggregations: { sales: { sum: { field: 'price' } } } }, hat_vs_bag_ratio: { bucket_script: { buckets_path: { hats: "sale_type['hat']>sales", bags: "sale_type['bag']>sales" }, script: 'params.hats / params.bags' } } } } } } ) puts response
POST /_search { "aggs": { "sales_per_month": { "date_histogram": { "field": "date", "calendar_interval": "month" }, "aggs": { "sale_type": { "terms": { "field": "type" }, "aggs": { "sales": { "sum": { "field": "price" } } } }, "hat_vs_bag_ratio": { "bucket_script": { "buckets_path": { "hats": "sale_type['hat']>sales", "bags": "sale_type['bag']>sales" }, "script": "params.hats / params.bags" } } } } } }
特殊路径编辑
除了指向指标之外,buckets_path
还可以使用特殊的 "_count"
路径。这指示管道聚合使用文档计数作为其输入。例如,可以在每个桶的文档计数上计算导数,而不是特定指标
response = client.search( body: { aggregations: { my_date_histo: { date_histogram: { field: 'timestamp', calendar_interval: 'day' }, aggregations: { the_deriv: { derivative: { buckets_path: '_count' } } } } } } ) puts response
POST /_search { "aggs": { "my_date_histo": { "date_histogram": { "field": "timestamp", "calendar_interval": "day" }, "aggs": { "the_deriv": { "derivative": { "buckets_path": "_count" } } } } } }
buckets_path
还可以使用 "_bucket_count"
并指向多桶聚合,以在管道聚合中使用该聚合返回的桶数,而不是指标。例如,bucket_selector
可以在这里用于过滤掉不包含内部 terms 聚合的桶的桶
response = client.search( index: 'sales', body: { size: 0, aggregations: { histo: { date_histogram: { field: 'date', calendar_interval: 'day' }, aggregations: { categories: { terms: { field: 'category' } }, min_bucket_selector: { bucket_selector: { buckets_path: { count: 'categories._bucket_count' }, script: { source: 'params.count != 0' } } } } } } } ) puts response
POST /sales/_search { "size": 0, "aggs": { "histo": { "date_histogram": { "field": "date", "calendar_interval": "day" }, "aggs": { "categories": { "terms": { "field": "category" } }, "min_bucket_selector": { "bucket_selector": { "buckets_path": { "count": "categories._bucket_count" }, "script": { "source": "params.count != 0" } } } } } } }
处理聚合名称中的点编辑
支持另一种语法来处理名称中包含点的聚合或指标,例如 99.9
th 百分位数。此指标可以称为
"buckets_path": "my_percentile[99.9]"
处理数据中的间隙编辑
现实世界中的数据通常很嘈杂,有时包含 间隙 — 数据根本不存在的地方。这可能由于多种原因发生,最常见的原因是
- 落入桶中的文档不包含必需的字段
- 没有文档匹配一个或多个桶的查询
- 正在计算的指标无法生成值,可能是因为另一个依赖桶缺少值。一些管道聚合有必须满足的特定要求(例如,导数无法为第一个值计算指标,因为没有先前的值,HoltWinters 移动平均需要“预热”数据才能开始计算,等等)
间隙策略是一种机制,用于告知管道聚合在遇到“间隙”或丢失数据时所需的行为。所有管道聚合都接受 gap_policy
参数。目前有两种间隙策略可供选择
- 跳过
- 此选项将丢失数据视为桶不存在。它将跳过桶并继续使用下一个可用值进行计算。
- 插入零
- 此选项将用零 (
0
) 替换丢失的值,管道聚合计算将照常进行。 - 保留值
- 此选项类似于跳过,除了如果指标提供非空、非 NaN 值,则使用此值,否则将跳过空桶。