Aggregations
ES 的聚合可以总结为三类:指标聚合、统计聚合、其他分析聚合。
- Metric aggregations: 计算
field
的指标值,例如平均值、最大值、和等指标 - Bucket aggregations: 基于
field
的值、范围、或其他标准对doc
分类,每一类都是一个bucket
或bin
- Pipeline aggregations: 通过其他 取代
doc
或者field
作为输入
rust
GET /my-index-000001/_search
{
"aggs": {
...
}
}
在查询中 aggs
的具体使用方法都在这一章,包括多个聚合查询、嵌套聚合查询等。
一、Bucket aggregations
桶(bucket
)聚合,根据 给出的 标准(criterion
)将 doc
放入不同的桶中,并统计在每个桶(bucket
)中的 文档(doc
)数量。桶(bucket
)聚合可以创建子聚合,子聚合是基于父聚合的结果进行创建。
search.max_buckets
该参数用于限制在查询中返回的桶的数量,桶(bucket
)聚合共有如下方法:
1.1 Adjacency matrix
一个桶聚合返回一个邻接矩阵。
1.2 Auto-interval date histogram
与 日期直方图(Date histogram) 类似的多数据桶聚合。日期直方图(Date histogram) 在聚合时根据给定的时间间隔进行聚合,结果中 桶(bucket
)的数量不确定,依赖于文档(doc
)中对应字段的数据范围。auto_date_histogram
聚合是给定桶(bucket
)的数量,由 ES 自动选择聚合的时间间隔。
rust
POST /sales/_search?size=0
{
"aggs": {
"sales_over_time": {
"auto_date_histogram": {
"field": "date",
"buckets": 10
}
}
}
}
1.3 Categorize text
对文本进行分类,将具有相似结果的 text
类型收纳到一个 桶(bucket
)中。
1.4 Children
一种特殊的单桶聚合,用于选择具有指定类型(如 join
类型)的子文档。
1.5 Composite
1.6 Date histogram
基于 时间(fidld
类型 为 date
)的直方图。尽管可以使用 普通的直方图,完成类似于 date_histogram
直方图的功能,但 date_histogram
为时间类型提供了更准确描述时间间隔的方式。
rust
POST /sales/_search?size=0
{
"aggs": {
"sales_over_time": {
"date_histogram": {
"field": "my_date",
"calendar_interval": "month"
}
}
}
}
查询 my_date
字段每个月的 文档(doc
)数量。
这里值得注意的是,时间间隔的选择有两种方式,一种是 周期间隔(Calendar intervals),另外一种是 固定间隔(Fixed intervals),分别对应参数 calendar_interval
和 fixed_interval
。
1.7 Date range
专门用于 时间(fidld
类型 为 date
)的范围聚合。该聚合与普通范围聚合的主要区别在于,from
和to
可以用日期数学表达式(Date Math )表示,而且还可以指定日期格式。date_range
此聚合包括from
字段的文档,但不包括每个范围内 to
所表示的文档。
rust
POST /my_index/_search?size=0
{
"aggs": {
"range": {
"date_range": {
"field": "@timestamp",
"time_zone": "CET",
"ranges": [
{ "to": "2016/02/01" },
{ "from": "2016/02/01", "to" : "now/d" },
{ "from": "now/d" }
]
}
}
}
}
1.8 Diversified sampler
1.9 Filter
缩小 聚合中的 文档集合。
rust
POST /sales/_search?size=0&filter_path=aggregations
{
"aggs": {
"avg_price": { "avg": { "field": "price" } },
"t_shirts": {
"filter": { "term": { "type": "t-shirt" } },
"aggs": {
"avg_price": { "avg": { "field": "price" } }
}
}
}
}
### response
{
"aggregations": {
"avg_price": { "value": 140.71428571428572 },
"t_shirts": {
"doc_count": 3,
"avg_price": { "value": 128.33333333333334 }
}
}
}
avg_price
返回 sales 索引中所有文档 price 字段的平均值t_shirts.avg_price
返回 sales 索引中 type 字段为 t-shirt 的文档 的 price 字段的平均值
1.10 Filters
1.11 Geo-distance
1.12 Geohash grid
1.13 Geohex grid
1.14 Geotile grid
1.15 Global
1.16 Histogram
直方图聚合:依据某个 field
的值,将数据按间隔,放入不同的 桶(bucket
)中。桶的取值范围和文档 该字段的取值范围一致。其中桶的 键 的计算方法为
b u c k e t k e y = M a t h . f l o o r ( ( v a l u e − o f f s e t ) / i n t e r v a l ) ∗ i n t e r v a l + o f f s e t bucket_key = Math.floor((value - offset) / interval) * interval + offset bucketkey=Math.floor((value−offset)/interval)∗interval+offset
第一个桶(bucket
)的 键 是根据 field
字段值的最小值计算出来的,最后一个桶(bucket
)的 键 以同样的方式用 field
字段值的最大值计算。
rust
POST /sales/_search?size=0
{
"aggs": {
"prices": {
"histogram": {
"field": "price",
"interval": 50
}
}
}
}
1.17 IP prefix
1.18 IP range
1.19 Missing
基于 索引 中所有文档(doc
),缺少的 缺少的某个 字段(field
)或 该字段(field
)的值为 NULL 的情况来创建桶。
rust
POST /sales/_search?size=0
{
"aggs": {
"products_without_a_price": {
"missing": { "field": "price" }
}
}
}
获得 sales 索引中,没有 price 字段或 price 字段值为 NULL 的 文档(doc
)总数。
1.20 Multi Terms
多个 terms
聚合的组合,主要用于 按文档数量排序,或按复合键的度量聚合排序并获得前 N 个结果时。
rust
GET /products/_search
{
"aggs": {
"genres_and_products": {
"multi_terms": {
"terms": [{
"field": "genre"
}, {
"field": "product"
}]
}
}
}
}
注意: 如果不断的使用同一组 field
做聚合查询,则可以将 本组 field
的值组合成新的 字段,并在新的字段上使用 terms
聚合。
1.20 Nested
1.21 Parent
1.22 Range
通过定义一组范围,其中每个范围代表一个桶。在聚合过程中,从每个文档(doc
)中提取的值将与每个桶范围进行核对,并将相关/匹配文档 放入桶(bucket
)。range
此聚合包括from
字段的文档,但不包括每个范围内 to
所表示的文档。
rust
GET sales/_search
{
"aggs": {
"price_ranges": {
"range": {
"field": "price",
"ranges": [
{ "to": 100.0 },
{ "from": 100.0, "to": 200.0 },
{ "from": 200.0 }
]
}
}
}
}
1.23 Rare terms
1.24 Reverse nested
1.25 Sampler
1.26 Significant terms
1.27 Significant text
1.28 Terms
根据 field
的值来创建桶(bucket
),field
中的每一个 值 都对应一个 桶(bucket
)
rust
GET /_search
{
"aggs": {
"genres": {
"terms": { "field": "genre" }
}
}
}
1.29 Variable width histogram
1.30 Subtleties of bucketing range fields
二、Metrics aggregations
计算 桶(bucket
)内,文档(doc
)某个字段(field
)的度量值。
2.1 Avg
平均值
rust
POST /exams/_search?size=0
{
"runtime_mappings": {
"grade.corrected": {
"type": "double",
"script": {
"source": "emit(Math.min(100, doc['grade'].value * params.correction))",
"params": {
"correction": 1.2
}
}
}
},
"aggs": {
"avg_corrected_grade": {
"avg": {
"field": "grade.corrected"
}
}
}
}
注意: 用于计算度量的字段可以来自于 文档(doc
)某个字段(field
),也可以来自于脚本结合 runtime field
字段。
2.2 Boxplot
箱图
2.3 Cardinality
估计某个字段(field
)内有多少个不同的值
rust
POST /sales/_search?size=0
{
"aggs": {
"type_count": {
"cardinality": {
"field": "type"
}
}
}
}
注意: 计算 type 字段内有多少个不同的值
2.4 Extended stats
一次统计 多个指标值,包括 min
(最小值)、max
(最大值)、sum
(求和)、count
(计数)、avg
(平均值)、sum_of_squares
()、variance
()、std_deviation
()、std_deviation_bounds
()
2.5 Geo-bounds
2.6 Geo-centroid
2.7 Geo-Line
2.8 Matrix stats
2.9 Max
最大值
2.10 Median absolute deviation
2.11 Min
最小值
2.12 Percentile ranks
某个值在 在百分位数的排名。
rust
GET latency/_search
{
"size": 0,
"aggs": {
"load_time_ranks": {
"percentile_ranks": {
"field": "load_time",
"values": [ 500, 600 ]
}
}
}
}
500, 600 这两个数字 在 load_time 字段中位置的百分比(load_time 字段的值从小到大依次排列)
2.13 Percentiles
百分位数聚合。
rust
GET latency/_search
{
"size": 0,
"aggs": {
"load_time_outlier": {
"percentiles": {
"field": "load_time",
"percents": [ 95, 99, 99.9 ]
}
}
}
}
latency 索引的 load_time 字段的 95
,99
,99.9
分位数。
2.14 Rate
2.15 Scripted metric
使用脚本执行的指标聚合以提供指标输出
2.16 Stats
一次统计 多个指标值, 包括 min
(最小值)、max
(最大值)、sum
(求和)、count
(计数)、avg
(平均值)
rust
POST /exams/_search?size=0
{
"aggs": {
"grades_stats": { "stats": { "field": "grade" } }
}
}
2.17 String stats
从 keyword
中一次统计 多个指标值, 包括 count
(计数,非空)、min_length
(最小长度)、max_length
(最大长度)、avg_length
(平均长度)、entropy
(香农熵)
2.18 Sum
求和
2.19 T-test
2.20 Top hits
取 桶(bucket
)内,按照 某种 排序(sort
)匹配度靠前(size
)的文档(doc
)
rust
POST /sales/_search?size=0
{
"aggs": {
"top_tags": {
"terms": {
"field": "type",
"size": 3
},
"aggs": {
"top_sales_hits": {
"top_hits": {
"sort": [
{
"date": {
"order": "desc"
}
}
],
"_source": {
"includes": [ "date", "price" ]
},
"size": 1
}
}
}
}
}
}
2.21 Top metrics
top_metrics
聚合按照 sort
排序,选择 size
个文档中,metrics
指定的字段返回。
rust
### 写入数据
POST /test/_bulk?refresh
{"index": {}}
{"s": 1, "m": 3.1415}
{"index": {}}
{"s": 2, "m": 1.0}
{"index": {}}
{"s": 3, "m": 2.71828}
### 查询
POST /test/_search?filter_path=aggregations
{
"aggs": {
"tm": {
"top_metrics": {
"metrics": {"field": "m"},
"sort": {"s": "desc"},
"size": 1
}
}
}
}
### Response
{
"aggregations": {
"tm": {
"top": [ {"sort": [3], "metrics": {"m": 2.718280076980591 } } ]
}
}
}
在 top_metrics
聚合中,文档(doc
)按照 s 字段排倒序("sort": {"s": "desc"}
),取前 1 个("size": 1
),返回 m 字段。
2.22 Value count
计数
2.23 Weighted avg
加权平均值
三、Pipeline aggregations
管道聚合(Pipeline aggregations)基于其他的聚合结果进行聚合,并将结果添加到聚合中,管道聚合主要分为两类
- Parent: (父级聚合)
管道聚合的一个系列,可获得其父聚合的输出,并能计算新的桶或新的聚合,以添加到现有的桶中。
同胞聚合 - Sibling: (同级聚合)
提供同级聚合输出的管道聚合,能够计算与同级聚合处于同一级别的新聚合。
3.1 Average bucket
Sibling 类
计算指定指标的平均值,指定的度量必须是数字。同级聚合必须是多桶聚合。
rust
PUT my_index
{
"mappings": {
"properties": {
"@timestamp" : {
"type" : "date",
"format" : "[yyyy/MM/dd]"
},
"my_field" : {
"type" : "keyword"
},
"my_other_field" : {
"type" : "float"
}
}
}
}
POST my_index/_bulk
{"index":{}}
{"@timestamp": "2024/03/01", "my_other_field": 5}
{"index":{}}
{"@timestamp": "2024/03/02", "my_other_field": 6}
{"index":{}}
{"@timestamp": "2024/04/01", "my_other_field": 7}
{"index":{}}
{"@timestamp": "2024/05/01", "my_other_field": 8}
POST my_index/_search
{
"size": 0,
"aggs": {
"sales_per_month": {
"date_histogram": {
"field": "@timestamp",
"calendar_interval": "month"
},
"aggs": {
"sales": {
"avg": {
"field": "my_other_field"
}
}
}
},
"avg_monthly_sales": {
"avg_bucket": {
"buckets_path": "sales_per_month>sales"
}
}
}
}
3.2 Bucket script
Parent 类
执行一个脚本,该脚本可以对父级多桶聚合中,每个桶指定的指标执行计算。指定的指标必须是数值,脚本必须返回数值。
rust
POST my_index/_search
{
"size": 0,
"aggs": {
"sales_per_month": {
"date_histogram": {
"field": "@timestamp",
"calendar_interval": "month"
},
"aggs": {
"sales": {
"avg": {
"field": "my_other_field"
}
},
"percentage": {
"bucket_script": {
"buckets_path": {
"tShirtSales": "sales",
"num": "_count"
},
"script": "params.tShirtSales / params.num * 100"
}
}
}
}
}
}
3.3 Bucket count K-S test
3.4 Bucket correlation
3.5 Bucket selector
3.6 Bucket sort
3.7 Cumulative cardinality
3.8 Cumulative sum
3.9 Derivative
Parent 类
用于计算父级直方图(或日期直方图)聚合中指定度量的导数,指定的度量值必须是数值。
rust
POST my_index/_search
{
"size": 0,
"aggs": {
"sales_per_month": {
"date_histogram": {
"field": "@timestamp",
"calendar_interval": "month"
},
"aggs": {
"sales": {
"avg": {
"field": "my_other_field"
}
},
"sales_deriv": {
"derivative": {
"buckets_path": "sales"
}
},
"sales_deriv2": {
"derivative": {
"buckets_path": "sales_deriv"
}
}
}
}
}
}