本地英文版地址: ../en/search-aggregations-pipeline.html
管道聚合处理其他聚合(而不是文档集)产生的输出,将信息添加到输出树中。 管道聚合有很多不同的类型,每一种都计算来自其他聚合的不同信息,但这些类型可以分为两类:
- Parent
- 一系列管道聚合,提供其父聚合的输出,并能够计算新桶或新聚合以添加到现有桶。
- Sibling
- 与同级聚合的输出提供的管道聚合,并且能够计算与同级聚合同级别的新聚合。
管道聚合可以引用执行计算所需的聚合,方法是使用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"桶聚合中。
路径相对于管道聚合位置; 它们不是绝对路径,并且路径不能回到聚合树的“上面”。
例如,下面这个查询将移动平均值嵌入在 date_histogram(日期直方图)中,并引用“Sibling”(同级)度量"the_sum":
POST /_search
{
"aggs": {
"my_date_histo":{
"date_histogram":{
"field":"timestamp",
"calendar_interval":"day"
},
"aggs":{
"the_sum":{
"sum":{ "field": "lemmings" }
},
"the_movavg":{
"moving_avg":{ "buckets_path": "the_sum" }
}
}
}
}
}
buckets_path还用于 Sibling 管道聚合,其中聚合位于一系列桶的“旁边”,而不是嵌入在桶的“内部”。
例如,max_bucket聚合使用buckets_path来指定嵌入在 Sibling 聚合中的度量:
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"
}
}
}
}
如果 Sibling 管道聚合引用一个多桶聚合,如terms聚合,它还可以选择从多桶中选择特定的键。
例如,bucket_script可以(通过它们的桶的键)选择两个特定的桶来执行计算:
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"路径,而不是一个度量的路径。
这将指示管道聚合使用文档数量作为其输入。
例如,可以根据每个时段的文档数计算移动平均值(moving_avg),而不是特定的度量:
POST /_search
{
"aggs": {
"my_date_histo": {
"date_histogram": {
"field":"timestamp",
"calendar_interval":"day"
},
"aggs": {
"the_movavg": {
"moving_avg": { "buckets_path": "_count" }
}
}
}
}
}
buckets_path还可以使用_bucket_count和多桶聚合的路径,以使用管道聚合中该聚合返回的桶数,而不是度量。
例如,这里可以使用bucket_selector来过滤出不包含内部词项聚合的桶:
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百分位数。
该度量可以这样引用:
"buckets_path": "my_percentile[99.9]"
处理数据中的间隙(gap)
现实世界中的数据通常是嘈杂的,有时包含间隙(gap),即数据根本不存在的地方。 出现这种情况有多种原因,最常见的是:
- 落入桶中的文档不包含必需的字段
- 没有与一个或多个桶的查询匹配的文档
- 正在计算的度量无法生成值,可能是因为另一个相关的桶缺少值。 一些管道聚合有必须满足的特定要求(例如,由于没有之前的值,导数(derivative)不能计算第一个值的度量,HoltWinters移动平均需要“预热”数据才能开始计算,等等)
间隙策略(gap policy)是一种机制,用于在遇到“间隙”或缺失数据时通知管道聚合所需的行为。
所有管道聚合都接受gap_policy参数。
目前有两种间隙策略可供选择:
- skip
- 此选项将缺失的数据视为桶不存在。 它将跳过这个桶,并使用下一个可用值继续计算。
- insert_zeros
-
此选项将用零(
0)替换缺失的值,管道聚合计算将照常进行。