文章目录
- 前言
- 桶聚合
- filters aggregation
- term aggregation
- 基本用法
- 配置选项
- 子聚合
- 注意事项
- 指标聚合
前言
ES 聚合运算在面向 C 端的日常开发中,比较少碰到。在面向公司内部,或者数据报表的开发中可能会碰到。
ES 聚合运算主要分为三大类:
- 桶聚合(
Bucket aggregations
) - 指标聚合(
Metrics aggregations
) - 管道聚合(
Pipeline aggregations
)
因为管道聚合开发中实在没碰到过,本篇章就不介绍了。
桶聚合
桶聚合允许你根据一个或多个维度对数据进行分组。
ES 桶聚合有非常多的用法,这里挑出开发中相对常用的进行介绍。更多内容需要到 ES 桶聚合官网查阅
filters aggregation
多桶聚合,其中每个桶包含与查询匹配的文档。
例如查询 type=A,type=B 的 score 平均值
POST test10/_bulk
{"index": {}}
{"type":"A","score":12,"pid":13}
{"index": {}}
{"type":"A","score":42,"pid":13}
{"index": {}}
{"type":"A","score":55,"pid":12}
{"index": {}}
{"type":"B","score":14,"pid":13}
{"index": {}}
{"type":"B","score":1213,"pid":13}
{"index": {}}
{"type":"B","score":324,"pid":12}
GET test10/_search
{"size": 0, "query": {"term": {"pid": {"value": 13}}},"aggs": {"my_filters": {"filters": {"filters": {"a_type": {"term": {"type.keyword": "A"}},"b_type": {"term": {"type.keyword": "B"}}}},"aggs": {"avg_score": {"avg": {"field": "score"}}}}}
}
term aggregation
term
聚合(terms aggregation
)是一种对数据进行分组的聚合操作,它基于一个字段的所有不同值(通常是关键词字段)来对数据进行分组。每个唯一的值都会成为一个“桶”(bucket),并且可以对这些桶进行各种统计分析,比如计数、求和、平均值等。
注:统计值只是一个预估值,非准确值。
基本用法
下面是一个基本的term
聚合的例子,它展示了如何在products
索引中根据category
字段的不同值来聚合文档,并计算每个类别的文档数量:
POST /products/_search
{"size": 0, "aggs": {"categories": {"terms": {"field": "category.keyword"}}}
}
在这个例子中,size
设置为0是因为我们只对聚合结果感兴趣,不需要返回任何文档。aggs
字段定义了聚合操作,其中 categories
是我们给这个聚合操作起的名字,terms
指定了我们想要进行的聚合类型,field
指定了我们想要聚合的字段。
配置选项
term
聚合有一些重要的配置选项:
field
:指定要聚合的字段。size
:指定返回的桶的数量。默认是10,可以设置一个更大的数字来返回更多的桶。shard_size
:在分片级别上设置桶的数量,这通常比size
大,因为每个分片会先收集桶,然后减少到size
指定的数量。min_doc_count
:指定每个桶至少需要包含的文档数量。如果设置为1,那么即使某个关键词只出现了一次也会被包含在结果中。order
:指定桶的排序方式。可以按照_count
(默认,按桶中的文档数量降序排序,不应该使用升序排序)、_term
(按词条字典顺序排序)或者自定义脚本等方式排序。
子聚合
term
聚合可以包含子聚合,这意味着你可以在每个桶的基础上进一步进行聚合。例如,你可以先按category
字段聚合,然后在每个类别内部按price
字段进行统计分析:
POST /products/_search
{"size": 0, "aggs": {"categories": {"terms": {"field": "category.keyword","size": 10},"aggs": {"average_price": {"avg": {"field": "price"}}}}}
}
在这个例子中,categories
聚合下的average_price
子聚合会计算每个类别的平均价格。
注意事项
term
聚合通常用于keyword
类型的字段,因为这些字段是全文本的,不会进行分词。- 对于文本字段,你可能需要先将文本字段的分词结果聚合起来,然后再进行
term
聚合。 - 大量的唯一值可能会导致大量的桶,这可能会消耗大量的内存和网络带宽,因此需要合理设置
size
和shard_size
。
指标聚合
指标聚合一般是用于对某一个字段进行算术运算。例如:求均值、求和、求最大值、求最小值、求文档数。
本篇只会选择其中一个介绍,其他内容大差不差。更详细信息请自行阅读 ES 指标聚合官网
求所有指标
GET test10/_search
{"size": 0, "aggs": {"my_stat": {"stats": {"field": "score"}}}
}
返回
{......"aggregations" : {"my_stat" : {"count" : 6,"min" : 12.0,"max" : 1213.0,"avg" : 276.6666666666667,"sum" : 1660.0}}
}