Elasticsearch入门教程:聚合查询
聚合前提:聚合是对query查询出来的数据进行聚合
(一)先举出几个需求例子:
1、基于studymodel字段分组,即数据中的group by studymodel
加上"size":0后,可以去掉搜索结果中的hit命中数据。
GET localhost:9200/book/_search
{
"size":0,
"query":{
"match_all":{}
},
"aggs":{
"group_by_model":{
"terms":{
"field":"studymodel"
}
}
}
}
2、计算每个tags下的商品数量
设置字段"fielddata":true
PUT localhost:9200/book/_mapping
{
"properties":{
"tage":{
"type":"text",
"fielddata":true
}
}
}
先分组,再算每组的平均值,计算每个tag下的商品的平均价格
GET localhost:9200/book/_search
{
"size":0,
"query":{
"match_all":{}
},
"aggs":{
"group_by_tags":{
"terms":{
"field":"tags",
},
"aggs":{
"avg_price":{
"avg":{
"field":"price"
}
}
}
}
}
}
计算每个tags下的商品的平均价格,并且按照平均价格降序排序
GET localhost:9200/book/_search
{
"size":0,
"query":{
"match_all":{}
},
"aggs":{
"group_by_tags":{
"terms":{
"field":"tags",
"order":{
"avg_price":"desc"
}
},
"aggs":{
"avg_price":{
"avg":{
"field":"price"
}
}
}
}
}
}
3、按照指定的价格区间进行分组,然后在每组内再按照tags进行分组,最后求在每个价格区间的每个tags下的平均价格
GET localhost:9200/book/_search
{
"size":0,
"query":{
"match_all":{}
},
"aggs":{
"group_by_price":{
"range:{
"field":"price",
"ranges":[
{
"from":0,
"to":40
},
{
"from":40,
"to":60
},
{
"from":60,
"to":80
}
]
},
"aggs":{
"group_by_tags":{
"term":{
"field":"tags"
},
"aggs":{
"avg":{
"field":"price"
}
}
}
}
}
}
}
(二)两个核心概念:bucket和metric
**bucket:**一个数据分组
**metric:**对一个数据分组执行的统计
1、划分范围histigram
histogram:类似于terms,也是进行bucket分组操作,接受一个field,按照这个field的值的各个范围区间,进行bucket分组操作
GET localhost:9200/tvs/_search
{
"size":0,
"query":{
"match_all":{}
},
"aggs":{
"price":{
"histogram":{
"field":"price",
"interval":2000
},
"aggs":{
"income":{
"sum":{
"field":"price"
}
}
}
}
}
}
interval:2000,划分范围,02000,20004000,40006000,60008000,8000~10000,buckets
bucket有了之后,一样的,去对每个bucket执行avg,count,sum,max,min,等各种metric操作,聚合分析
2、按照日期分组聚合
date_histogram,按照我们指定的某个date类型的日期field,以及日期interval,按照一定的日期间隔,去划分bucket
interval(时间间隔)的可用表达式:
- year(1y)年
- quarter(1q)季度
- month(1M)月份
- week(1w)星期
- day(1d)天
- hour(1h)小时
- minute(1m)分钟
- second(1s)秒
min_doc_count:即使某个日期interval,2007-01-01~2007-01-31中,一条数据都没有,那么这个区间也是要返回的,不然默认是会过滤掉这个区间的
GET localhost:9200/tvs/_search
{
"size":0,
"query":{
"match_all":{}
},
aggs:{
"group_by_data":{
"data_histogram":{
// 需要聚合分组的字段名称, 类型需要为date, 格式没有要求
"field": "@timestamp",
// 按什么时间段聚合, 这里是5分钟, 可用的interval在上面给出
"interval": "5m",
// 设置时区, 这样就相当于东八区的时间,ES默认是UTC时间,项目中需设置成东八区
"time_zone":"+08:00",
// 返回值格式化,HH大写,不然不能区分上午、下午
"format": "yyyy-MM-dd HH",
// 为空的话则填充0
"min_doc_count": 0,
// 需要填充0的范围
"extended_bounds": {
"min": 1533556800000,
"max": 1533806520000
}
},
"aggs":{
"avg_price":{
"avg":{
"field":"price"
}
}
}
}
}
}
3、global bucket:单个品牌与所有品牌的销量对比
aggregation,scope,一个聚合操作,必须在query的搜索结果范围内执行
出来两个结果,一个结果,是基于query搜索结果来聚合的;一个结果,是对所有数据执行聚合的
GET localhost:9200/tvs/_search
{
"size":0,
"query":{
"term":{
"brand":{
"value":"小米"
}
}
},
"aggs":{
"single_brand_avg_price":{
"avg":{
"field":"price"
}
},
"all":{
"global":{},
"aggs":{
"all_brand_avg_price":{
"avg":{
"field":"price"
}
}
}
}
}
}