本文来说一个ES中极其重要的一个概念,就是聚合,聚合功能是一个十分方便的功能。
一、ES的聚合分析
1、什么是聚合(Aggregation)
1、ES除了文本搜索之外,提供了针对ES数据进行统计分析的功能
- 实时性高
- Hadoop有时候是T+1的实现,es的聚合做的比较好
2、通过聚合,我们会得到一个数据的概览,是分析和总结全套的数据,而不是寻找单个文档。
- 比如查找大同和北京的酒店数量
- 不同的价格区间,可以预定的经济型酒店和五星级酒店的数量
3、高性能,只需要一条1语句,就可以从es得到分析结果
- 无需再客户端自己去聚合逻辑,全部交由ES服务端
2、聚合的使用场景
关于聚合,我们举几个例子来看看到底是干啥用的。
1、公司程序员的工作岗位分布
2、公司采用的编程框架分布
3、公司的薪资分布
4、客户的地理位置分布
5、订单的增长情况
我们可以看到,聚合其实就是对于一些分布的统计得到一些统筹的数据结果。
3、聚合的分类
1、Bucket Aggregation
索引中的那些列满足特定条件的文档的集合,类似于把满足条件的数据文档分在一个个的桶里面,这就能得到一个分布情况。
2、Metric Aggregation
一些数学运算,可以对文档字段进行统计非恩熙,比如得到最大值,最小值,平均值之类的。
3、Pipeline Aggregation
对于其他的聚合结果进行二次聚合。
4、Matrix Aggregation
支持对多个字段的操作,并且提供一个结果矩阵。
4、Bucket && Metric
翻译一下就是分组和统计。
我们可以结合着MYSQL中的一些概念,借助关系型数据库的思想更加符合人的思维。
4.1、Bucket
翻译一下就是分桶,分组。把数据按照类别分组到一起,还支持二次分桶。
比如项目中的商品数据,我们可以根据价格分组为高档,中档,抵挡三组数据。
我们可以为之打分根据打分分为优质,中等,一般三种数据。
举个例子:
从属关系:大同属于山西,
嵌套关系:大同属于山西,山西属于中国
ES还提供了很多类型的Bucket,帮助用多种方式划分文档。
比如Term & Range(时间,年龄区间,地理位置等等)
4.2、Metric
1、Metric是基于数据集计算结果,除了支持在字段上进行计算,同样也支持在脚本(painless script)产生的结果纸上进行计算。
2、大多数的Metric是数学计算,仅仅输出一个值
比如min / max / sum / avg / cardinality
3、部分Metric支持输出多个数值
比如stats输出平均,最大,最小
比如percentiles百分位,输出百分位点的分布,有点像普罗米修斯
比如percentiles_ranks
5、一个Bucket的例子
首先kibana_sample_data_flights索引是当时安装kibana的时候官方的数据导入的。这个索引里面存储这航班的一些信息数据。
5.1、查看航班目的地的统计信息
#按照目的地进行分桶统计
GET kibana_sample_data_flights/_search
{
"size": 0,
"aggs":{
"flight_dest":{ 分桶之后展示的别名,类似Mysql里面的as
"terms":{ 按照terms进行分桶
"field":"DestCountry"航班目的地进行分组
}
}
}
}
按照terms进行分桶就是按照文本,比如你名字叫张三,就叫张三的都在一个桶里面,最常见的分组,term在es中就是词汇的意思。
分桶结果如下:
"aggregations" : {
"flight_dest" : {这就是那别名
"doc_count_error_upper_bound" : 0,
"sum_other_doc_count" : 3187,
"buckets" : [
{
"key" : "IT", 去意大利的有2371趟航班
"doc_count" : 2371
},
{
"key" : "US",
"doc_count" : 1987
},
{
"key" : "CN",
"doc_count" : 1096
},
{
"key" : "CA",
"doc_count" : 944
},
{
"key" : "JP",
"doc_count" : 774
},
{
"key" : "RU",
"doc_count" : 739
},
{
"key" : "CH",
"doc_count" : 691
},
{
"key" : "GB",
"doc_count" : 449
},
{
"key" : "AU",
"doc_count" : 416
},
{
"key" : "PL",
"doc_count" : 405
}
]
}
}
这样就统计出了去往哪里的航班数,做了一个简单的分桶查询。
5.2、查看航班目的地的统计信息,增加平均,最高最低价格
我们上面按照航班目的地分组了,我们现在还想在目的地分组的基础上,增加均价,最高最低价格的分组结果。
GET kibana_sample_data_flights/_search
{
"size": 0,
"aggs":{ 外层分组,按照目的地航班
"flight_dest":{
"terms":{
"field":"DestCountry"
},
"aggs":{ 分组之上再加分组
"avg_price":{ 取个别名
"avg":{ 是取平均值
"field":"AvgTicketPrice"
}
},
"max_price":{
"max":{ 取最大值
"field":"AvgTicketPrice"
}
},
"min_price":{
"min":{ 取最小值
"field":"AvgTicketPrice"
}
}
}
}
}
}
上面语句的意思就是,先按照航班目的地分组,然后在每个分组内部,取得每个分组的平均值,最大值,最小值。
查询结果如下:
"aggregations" : {
"flight_dest" : {
"doc_count_error_upper_bound" : 0,
"sum_other_doc_count" : 3187,
"buckets" : [
{
"key" : "IT", 去意大利的分组
"doc_count" : 2371, 有2371趟航班
"max_price" : { 去意大利最贵的机票价格
"value" : 1195.3363037109375
},
"min_price" : {去意大利最便宜的几篇价格
"value" : 100.57646942138672
},
"avg_price" : {去意大利平均机票价格
"value" : 586.9627099618385
}
},
{
"key" : "JP",
"doc_count" : 774,
"max_price" : {
"value" : 1199.4913330078125
},
"min_price" : {
"value" : 103.97209930419922
},
"avg_price" : {
"value" : 650.9203447346847
}
},
{
"key" : "RU",
"doc_count" : 739,
"max_price" : {
"value" : 1196.7423095703125
},
"min_price" : {
"value" : 101.0040054321289
},
"avg_price" : {
"value" : 662.9949632162009
}
}
]
}
}
5.3、价格统计信息+天气信息
查看航班目的地的统计信息,平均票价,以及天气状况。
GET kibana_sample_data_flights/_search
{
"size": 0,
"aggs":{
"flight_dest":{去别名
"terms":{
"field":"DestCountry"按照目的地的词汇分组
},
"aggs":{
"stats_price":{取别名
"stats":{ 这个救赎输出多个的结果的指标是多个metric
"field":"AvgTicketPrice"
}
},
"wather":{取别名
"terms": {
"field": "DestWeather",
"size": 5 只统计五个桶,也就是只显示分出五个类别,具体怎么取后面看
}
}
}
}
}
}
输出结果如下:
"aggregations" : {
"flight_dest" : {
"doc_count_error_upper_bound" : 0,
"sum_other_doc_count" : 3187,
"buckets" : [
{
"key" : "US",
"doc_count" : 1987, 去美国的航班有1987个,下面是这1987个航班里面的天气分组
"wather" : {
"doc_count_error_upper_bound" : 0,
"sum_other_doc_count" : 438,
"buckets" : [
{
"key" : "Rain", 下雨天的有371个,下面的都是晴天多云之类的,总共五个
"doc_count" : 371
},
{
"key" : "Clear",
"doc_count" : 346
},
{
"key" : "Sunny",
"doc_count" : 345
},
{
"key" : "Cloudy",
"doc_count" : 330
},
{
"key" : "Heavy Fog",
"doc_count" : 157
}
]
},
"stats_price" : {这个就是输出多个指标结果的
"count" : 1987, 总共是1987个
"min" : 100.14596557617188, 最小票价是
"max" : 1199.72900390625,最大票价
"avg" : 595.7743908825026,
"sum" : 1183803.7146835327
}
},
bucket和metric都是聚合的种类。
二、总结
就是分组和统计,记得对应Mysql理解,然后多加使用。
顺便提一嘴,这就是京东的聚合。