ElasticSearch笔记-聚合查询
概述
聚合查询,它是在搜索的结果上,提供的一些聚合数据信息的方法。比如:求和、最大值、平均数等。
聚合查询可以分为:bucket聚合查询、metrics聚合查询
指标聚合(metric)查询:相当于MYSQL的聚合函数,对数据分组进行统计,如max、min、avg、sum等
桶聚合(bucket)查询:相当于MYSQL的group by,作用是对数据分组。不要对text类型数据进行分组,会失败
为什么对text类型数据进行分组,会失败?
因为text类型会进行分词,分完词后会通过词条存储,分组是希望字段整体和其他的去比对,所以会失败
指标聚合案例
求全部学生的平均分数
GET index5/_search
{
"size": 0,
"query": {
"match_all": {}
},
"aggs": {
"avg_fenshu": {
"avg": {
"field": "fenshu"
}
}
}
}
aggs:appgregations的缩写
avg_fenshu:聚合名称
求全部学生的总分、平均分、最大分、最小分
GET index6/_search
{
"size": 0,
"query": {
"match_all": {}
},
"aggs": {
"fenshu_sum": {
"sum": {
"field": "fenshu"
}
},
"fenshu_avg": {
"avg": {
"field": "fenshu"
}
},
"fenshu_max": {
"max": {
"field": "fenshu"
}
},
"fenshu_min": {
"min": {
"field": "fenshu"
}
}
}
}
桶聚合查询案例
统计每个年龄有多少人
根据年龄分组
GET index5/people/_search
{
"size":0,
"aggs": {
"age_group": {
"terms": {
"field": "age"
}
}
}
}
查询结果中可以得到每个分组的数量,这仅是一个bucket操作,doc_count是bucket操作默认执行的一个内置metric
统计每个班级的平均年龄
需要在bucket查询的基础上,再metrics查询
统计班级的平均年龄,根据班级分组,再对每个bucket执行一个metric聚合统计操作
GET index5/people/_search
{
"size":0,
"aggs": {
"sex_group": {
"terms": {
"field": "classid"
},
"aggs": {
"avg_age": {
"avg": {
"field": "age"
}
}
}
}
}
}
下钻
下钻的意思是在分组的基础上在进行分组,比如在班级分组的基础上再对年龄分组,最后对每个最小粒度的分组执行聚合分析操作,年龄分组的基础上计算平均分数
也就是需要两个bucket查询,一个metrics查询
GET index5/people/_search
{
"size":0,
"aggs": {
"sex_group": {
"terms": {
"field": "classid"
},
"aggs": {
"age_group": {
"terms": {
"field": "age"
},
"aggs":{
"avg_fenshu":{
"avg": {
"field": "fenshu"
}
}
}
}
}
}
}
}
查找每个班级最高分、最低分、平均分
需要使用多个metric,对bucket分析
GET index5/people/_search
{
"size":0,
"aggs": {
"class_group":{
"terms": {
"field": "classid"
},
"aggs": {
"avg_age": {
"avg": {
"field": "age"
}
},
"max_age":{
"max": {
"field": "age"
}
},
"min_age":{
"min":{
"field": "age"
}
}
}
}
}
}
按年龄区间统计平均分数
GET index5/people/_search
{
"size":0,
"aggs": {
"age_group": {
"histogram": {
"field": "age",
"interval": 1
},
"aggs": {
"fenshu": {
"avg": {
"field": "fenshu"
}
}
}
}
}
}
按时间区间统计平均分数
GET index5/people/_search
{
"size":0,
"aggs": {
"age_group": {
"date_histogram": {
"field": "birthday",
"interval": "year",
"format": "yyyy-MM-dd",
"min_doc_count": 0,
"extended_bounds": {
"min": "1985-01-01",
"max": "2020-01-01"
}
},
"aggs": {
"avg_fenshu": {
"avg": {
"field": "fenshu"
}
}
}
}
}
}
global bucket
global bucket可排除查询条件,用于整体与按条件查询结果对比
查询1班的平均成绩与全部班级的平均成绩
GET index6/user/_search
{
"size":0,
"query": {
"term": {
"classid": {
"value": 3
}
}
},
"aggs": {
"age_avg": {
"avg": {
"field": "age"
}
},
"all_user":{
"global": {},
"aggs": {
"global_avg_fenshu": {
"avg": {
"field": "fenshu"
}
}
}
}
}
}
过滤bucket
aggs.filter,针对聚合过滤
如果filter放query里,是全局的。如果想对统计结果过滤,需要将filter放在aggs中
搜索1班90年出生学生的平均成绩
GET index5/people/_search
{
"size": 0,
"query": {
"match": {
"classid": 1
}
},
"aggs": {
"recent_90":{
"filter": {
"range": {
"birthday": {
"gte": "1990/01/01",
"lte": "1991/01/01"
}
}
},
"aggs": {
"avg_fenshu": {
"avg": {
"field": "fenshu"
}
}
}
}
}
}
排序
对分析的结果排序
按班级分组,并按平均分数排序
GET index5/people/_search
{
"size": 0,
"aggs": {
"class_group": {
"terms": {
"field": "classid",
"order": {
"avg_fenshu": "desc"
}
},
"aggs": {
"avg_fenshu": {
"avg": {
"field": "fenshu"
}
}
}
}
}
}
去重
对每个bucket中指定field进行去重,取去重后的count,类似count(distinct)
GET index5/people/_search
{
"size": 0,
"aggs": {
"years": {
"date_histogram": {
"field": "birthday",
"interval": "year",
"format": "yyyy-MM-dd",
"min_doc_count": 0,
"extended_bounds": {
"min": "1985-01-01",
"max": "2020-01-01"
}
},
"aggs": {
"age_distinct": {
"cardinality": {
"field": "age"
}
}
}
}
}
}