文章目录
- 前言
- 一、指标聚合
- 1、统计最大值:Max Aggregation
- 2、统计最小值:Min Aggregation
- 3、统计平均值:Avg Aggregation
- 4、求和:Sum Aggregation
- 5、Cardinality Aggregation
- 6、基本统计:Stats Aggregation
- 7、高级统计:Extends Stats Aggregation
- 8、百分位统计:Percentiles Aggregation
- 9、按照字段统计:Value Count Aggregation
- 二、桶聚合(bucket)
- 1、分组聚合:Terms Aggregation
- 2、过滤器聚合:Filter Aggregation
- 3、多过滤器聚合:Filters Aggregation
- 4、按照范围聚合:Range Aggregation
- 5、范围聚合:Date Range Aggregation
- 6、时间直方图聚合:Date Histogram Aggregation
- 7、空值聚合:Missing Aggregation
- 8、Children Aggregation
- 9、地理位置数据统计:Geo Distance Aggregation
- 10、IP 地址范围查询:IP Range Aggregation
- 三、 管道聚合
- 1、计算聚合平均值:Avg Bucket Aggregation
- 2、Max Bucket Aggregation
- 3、Min Bucket Aggregation
- 4、Sum Bucket Aggregation
- 5、Stats Bucket Aggregation
- 6、Extended Stats Bucket Aggregation
- 7、Percentiles Bucket Aggregation
- 总结
前言
这篇文档就简单记录哈ES中的聚合分析,包括指标聚合
、桶聚合
、管道聚合
。其实就是数据库中的各类分析函数,比如max()
、min()
、avg()
、group b
y、havin
g等等。主要应用在一些统计分析业务中。
一、指标聚合
1、统计最大值:Max Aggregation
查询建筑最高的楼层:
GET /building_info/_search
{
"aggs": {
"max_floor": {
"max": {
"field": "floor"
}
}
}
}
查询结果如下:
如果字段不存在:
GET /building_info/_search
{
"aggs": {
"max_floor": {
"max": {
"field": "floor1",
"missing": 6
}
}
}
}
如果某个文档中缺少 floor1字段,则设置该字段的值为 6。
也可以通过脚本来查询最大值:
GET /building_info/_search
{
"aggs": {
"max_floor": {
"max": {
"script": {
"source": "if(doc['floor'].size()!=0){doc.floor.value}"
}
}
}
}
}
使用脚本时,可以先通过 doc['floor'].size()!=0
去判断文档是否有对应的属性。
2、统计最小值:Min Aggregation
统计最小值,用法和 Max Aggregation 基本一致:
GET /building_info/_search
{
"aggs": {
"min_floor": {
"min": {
"field": "floor",
"missing": 6
}
}
}
}
脚本:
GET /building_info/_search
{
"aggs": {
"min_floor": {
"min": {
"script": {
"source": "if(doc['floor'].size()!=0){doc.floor.value}"
}
}
}
}
}
3、统计平均值:Avg Aggregation
统计平均值:
GET /building_info/_search
{
"aggs": {
"avg_floor": {
"avg": {
"field": "floor"
}
}
}
}
GET /building_info/_search
{
"aggs": {
"avg_floor": {
"avg": {
"script": {
"source": "if(doc['floor'].size()!=0){doc.floor.value}"
}
}
}
}
}
4、求和:Sum Aggregation
求和:
GET /building_info/_search
{
"aggs": {
"sum_floor": {
"sum": {
"field": "floor"
}
}
}
}
GET /building_info/_search
{
"aggs": {
"sum_floor": {
"sum": {
"script": {
"source": "if(doc['floor'].size()!=0){doc.floor.value}"
}
}
}
}
}
5、Cardinality Aggregation
cardinality aggregation 用于基数统计。类似于 SQL 中的 distinct count(0)。
text 类型是分析型类型,默认是不允许进行聚合操作的,如果相对 text 类型进行聚合操作,需要设置其 fielddata 属性为 true,这种方式虽然可以使 text 类型进行聚合操作,但是无法满足精准聚合,如果需要精准聚合,可以设置字段的子域为 keyword。
- 1、方式一:
定义 books 索引:
PUT books
{
"mappings": {
"properties": {
"name":{
"type": "text",
"analyzer": "ik_max_word"
},
"publish":{
"type": "text",
"analyzer": "ik_max_word",
"fielddata": true
},
"type":{
"type": "text",
"analyzer": "ik_max_word"
},
"author":{
"type": "keyword"
},
"info":{
"type": "text",
"analyzer": "ik_max_word"
},
"price":{
"type": "double"
}
}
}
}
重新插入数据,然后查询出版社的总数量:
GET books/_search
{
"aggs": {
"publish_count": {
"cardinality": {
"field": "publish"
}
}
}
}
查询结果如下:
这种聚合方式可能会不准确。可以将 publish 设置为 keyword 类型或者设置子域为 keyword。
- 2、方式二
PUT books
{
"mappings": {
"properties": {
"name":{
"type": "text",
"analyzer": "ik_max_word"
},
"publish":{
"type": "keyword"
},
"type":{
"type": "text",
"analyzer": "ik_max_word"
},
"author":{
"type": "keyword"
},
"info":{
"type": "text",
"analyzer": "ik_max_word"
},
"price":{
"type": "double"
}
}
}
}
结果如下:
对比查询结果可知,使用 fileddata 的方式,查询结果不准确。
6、基本统计:Stats Aggregation
基本统计,一次性返回 count、max、min、avg、sum:
GET books/_search
{
"aggs": {
"stats_query": {
"stats": {
"field": "price"
}
}
}
}
结果如下:
7、高级统计:Extends Stats Aggregation
高级统计,比 stats 多出来:平方和、方差、标准差、平均值加减两个标准差的区间:
GET books/_search
{
"aggs": {
"es": {
"extended_stats": {
"field": "price"
}
}
}
}
8、百分位统计:Percentiles Aggregation
百分位统计:
GET books/_search
{
"aggs": {
"p": {
"percentiles": {
"field": "price",
"percents": [
1,
5,
10,
15,
25,
50,
75,
95,
99
]
}
}
}
}
9、按照字段统计:Value Count Aggregation
可以按照字段统计文档数量(包含指定字段的文档数量):
GET books/_search
{
"aggs": {
"count": {
"value_count": {
"field": "price"
}
}
}
}
二、桶聚合(bucket)
1、分组聚合:Terms Aggregation
Terms Aggregation 用于分组聚合,例如,统计各个出版社出版的图书总数量:
GET books/_search
{
"aggs": {
"NAME": {
"terms": {
"field": "publish",
"size": 20
}
}
}
}
结果如下:
在 terms 分桶的基础上,还可以对每个桶进行指标聚合。
统计不同出版社所出版的图书的平均价格:
GET books/_search
{
"aggs": {
"NAME": {
"terms": {
"field": "publish",
"size": 20
},
"aggs": {
"avg_price": {
"avg": {
"field": "price"
}
}
}
}
}
}
结果如下:
2、过滤器聚合:Filter Aggregation
过滤器聚合。可以将符合过滤器中条件的文档分到一个桶中,然后可以求其平均值。
例如查询书名中包含 java 的图书的平均价格:
GET books/_search
{
"aggs": {
"NAME": {
"filter": {
"term": {
"name": "java"
}
},
"aggs": {
"avg_price": {
"avg": {
"field": "price"
}
}
}
}
}
}
3、多过滤器聚合:Filters Aggregation
多过滤器聚合。过滤条件可以有多个。
例如查询书名中包含 java 或者 office 的图书的平均价格:
GET books/_search
{
"aggs": {
"NAME": {
"filters": {
"filters": [
{
"term":{
"name":"java"
}
},{
"term":{
"name":"office"
}
}
]
},
"aggs": {
"avg_price": {
"avg": {
"field": "price"
}
}
}
}
}
}
4、按照范围聚合:Range Aggregation
按照范围聚合,在某一个范围内的文档数统计。
例如统计图书价格在 0-50、50-100、100-150、150以上的图书数量:
GET books/_search
{
"aggs": {
"NAME": {
"range": {
"field": "price",
"ranges": [
{
"to": 50
},{
"from": 50,
"to": 100
},{
"from": 100,
"to": 150
},{
"from": 150
}
]
}
}
}
}
5、范围聚合:Date Range Aggregation
Range Aggregation 也可以用来统计日期,但是也可以使用 Date Range Aggregation,后者的优势在于可以使用日期表达式。
构造数据:
PUT blog/_doc/1
{
"title":"java",
"date":"2018-12-30"
}
PUT blog/_doc/2
{
"title":"java",
"date":"2020-12-30"
}
PUT blog/_doc/3
{
"title":"java",
"date":"2022-10-30"
}
统计一年前到一年后的博客数量:
GET blog/_search
{
"aggs": {
"NAME": {
"date_range": {
"field": "date",
"ranges": [
{
"from": "now-12M/M",
"to": "now+1y/y"
}
]
}
}
}
}
说明
:
1、12M/M 表示 12 个月。
2、1y/y 表示 1年。
3、d 表示天。
6、时间直方图聚合:Date Histogram Aggregation
时间直方图聚合。
例如统计各个月份的博客数量:
GET blog/_search
{
"aggs": {
"NAME": {
"date_histogram": {
"field": "date",
"calendar_interval": "month"
}
}
}
}
7、空值聚合:Missing Aggregation
空值聚合。
统计所有没有 price 字段的文档:
GET books/_search
{
"aggs": {
"NAME": {
"missing": {
"field": "price"
}
}
}
}
8、Children Aggregation
可以根据父子文档关系进行分桶。
查询子类型为 student 的文档数量:
GET stu_class/_search
{
"aggs": {
"NAME": {
"children": {
"type": "student"
}
}
}
}
9、地理位置数据统计:Geo Distance Aggregation
对地理位置数据做统计。
例如查询(34.288991865037524,108.9404296875)坐标方圆 600KM 和 超过 600KM 的城市数量:
GET geo/_search
{
"aggs": {
"NAME": {
"geo_distance": {
"field": "location",
"origin": "34.288991865037524,108.9404296875",
"unit": "km",
"ranges": [
{
"to": 600
},{
"from": 600
}
]
}
}
}
}
10、IP 地址范围查询:IP Range Aggregation
IP 地址范围查询:
GET blog/_search
{
"aggs": {
"NAME": {
"ip_range": {
"field": "ip",
"ranges": [
{
"from": "127.0.0.5",
"to": "127.0.0.11"
}
]
}
}
}
}
三、 管道聚合
管道聚合相当于在之前聚合的基础上,再次聚合。
1、计算聚合平均值:Avg Bucket Aggregation
计算聚合平均值。
例如,统计每个出版社所出版图书的平均值,然后再统计所有出版社的平均值:
GET books/_search
{
"aggs": {
"book_count": {
"terms": {
"field": "publish",
"size": 3
},
"aggs": {
"book_avg": {
"avg": {
"field": "price"
}
}
}
},
"avg_book":{
"avg_bucket": {
"buckets_path": "book_count>book_avg"
}
}
}
}
2、Max Bucket Aggregation
统计每个出版社所出版图书的平均值,然后再统计平均值中的最大值:
GET books/_search
{
"aggs": {
"book_count": {
"terms": {
"field": "publish",
"size": 3
},
"aggs": {
"book_avg": {
"avg": {
"field": "price"
}
}
}
},
"avg_book":{
"max_bucket": {
"buckets_path": "book_count>book_avg"
}
}
}
}
3、Min Bucket Aggregation
统计每个出版社所出版图书的平均值,然后再统计平均值中的最小值:
GET books/_search
{
"aggs": {
"book_count": {
"terms": {
"field": "publish",
"size": 3
},
"aggs": {
"book_avg": {
"avg": {
"field": "price"
}
}
}
},
"avg_book":{
"min_bucket": {
"buckets_path": "book_count>book_avg"
}
}
}
}
4、Sum Bucket Aggregation
统计每个出版社所出版图书的平均值,然后再统计平均值之和:
GET books/_search
{
"aggs": {
"book_count": {
"terms": {
"field": "publish",
"size": 3
},
"aggs": {
"book_avg": {
"avg": {
"field": "price"
}
}
}
},
"avg_book":{
"sum_bucket": {
"buckets_path": "book_count>book_avg"
}
}
}
}
5、Stats Bucket Aggregation
统计每个出版社所出版图书的平均值,然后再统计平均值的各种数据:
GET books/_search
{
"aggs": {
"book_count": {
"terms": {
"field": "publish",
"size": 3
},
"aggs": {
"book_avg": {
"avg": {
"field": "price"
}
}
}
},
"avg_book":{
"stats_bucket": {
"buckets_path": "book_count>book_avg"
}
}
}
}
6、Extended Stats Bucket Aggregation
GET books/_search
{
"aggs": {
"book_count": {
"terms": {
"field": "publish",
"size": 3
},
"aggs": {
"book_avg": {
"avg": {
"field": "price"
}
}
}
},
"avg_book":{
"extended_stats_bucket": {
"buckets_path": "book_count>book_avg"
}
}
}
}
7、Percentiles Bucket Aggregation
GET books/_search
{
"aggs": {
"book_count": {
"terms": {
"field": "publish",
"size": 3
},
"aggs": {
"book_avg": {
"avg": {
"field": "price"
}
}
}
},
"avg_book":{
"percentiles_bucket": {
"buckets_path": "book_count>book_avg"
}
}
}
}
总结
文章只是简单记录了怎么使用ES的简单统计查询,主要是因为太多或者久了不使用就会忘记一些使用方式,故在此记录。更多详情还是查询官网。