oracle竖列的数据怎么变成一行
301
2022-11-09
Elasticsearch系列---聚合查询(一)
概要
Elasticsearch的聚合查询,跟数据库的聚合查询效果是一样的,我们可以将二者拿来对比学习,如求和、求平均值、求最大最小等等。
基础概念
bucket
数据分组,一些数据按照某个字段进行bucket划分,这个字段值相同的数据放到一个bucket中。可以理解成Java中的Map
metric:
对一个数据分组执行的统计,比如计算最大值,最小值,平均值等类似于Mysql中的max(),min(),avg()函数的值,都是在group by后使用的。
案例
我们还是以英文儿歌为案例背景,回顾一下索引结构:
PUT /music { "mappings": { "children": { "properties": { "id": { "type": "keyword" }, "author_first_name": { "type": "text", "analyzer": "english" }, "author_last_name": { "type": "text", "analyzer": "english" }, "author": { "type": "text", "analyzer": "english", "fields": { "keyword": { "type": "keyword", "ignore_above": 256 } } }, "name": { "type": "text", "fields": { "keyword": { "type": "keyword", "ignore_above": 256 } } }, "content": { "type": "text", "fields": { "keyword": { "type": "keyword", "ignore_above": 256 } } }, "language": { "type": "text", "analyzer": "english", "fielddata": true }, "tags": { "type": "text", "analyzer": "english" }, "length": { "type": "long" }, "likes": { "type": "long" }, "isRelease": { "type": "boolean" }, "releaseDate": { "type": "date" } } } } }
统计目前收录的哪种语言的歌曲最多
GET /music/children/_search { "size": 0, "aggs": { "song_qty_by_language": { "terms": { "field": "language" } } } }
语法解释:
响应结果如下:
{ "took": 2, "timed_out": false, "_shards": { "total": 5, "successful": 5, "skipped": 0, "failed": 0 }, "hits": { "total": 5, "max_score": 0, "hits": [] }, "aggregations": { "song_qty_by_language": { "doc_count_error_upper_bound": 0, "sum_other_doc_count": 0, "buckets": [ { "key": "english", "doc_count": 5 } ] } } }
语法解释:
默认按doc_count降序排序。
按语种统计每种歌曲的平均时长
GET /music/children/_search { "size": 0, "aggs": { "lang": { "terms": { "field": "language" }, "aggs": { "length_avg": { "avg": { "field": "length" } } } } } }
这里演示的是两层aggs聚合查询,先按语种统计,得到数据分组,再在数据分组里算平均时长。
多个aggs嵌套语法也是如此,注意一下aggs代码块的位置即可。
统计最长时长、最短时长等的歌曲
最常用的统计:count,avg,max,min,sum,语法含义与mysql相同。
GET /music/children/_search { "size": 0, "aggs": { "color": { "terms": { "field": "language" }, "aggs": { "length_avg": { "avg": { "field": "length" } }, "length_max": { "max": { "field": "length" } }, "length_min": { "min": { "field": "length" } }, "length_sum": { "sum": { "field": "length" } } } } } }
按时长分段统计歌曲平均时长
以30秒为一段,看各段区间的平均值。
histogram语法位置跟terms一样,作范围分区,搭配interval参数一起使用interval:30表示分的区间段为[0,30),[30,60),[60,90),[90,120)
段的闭合关系是左开右闭,如果数据在某段区间内没有,也会返回空的区间。
GET /music/children/_search { "size": 0, "aggs": { "sales_price_range": { "histogram": { "field": "length", "interval": 30 }, "aggs": { "length_avg": { "avg": { "field": "length" } } } } } }
这种数据的结果可以用来生成柱状图或折线图。
按上架日期分段统计新歌数量
按月统计
date histogram与histogram语法类似,搭配date interval指定区间间隔extended_bounds表示最大的时间范围。
GET /music/children/_search { "size": 0, "aggs": { "sales": { "date_histogram": { "field": "releaseDate", "interval": "month", "format": "yyyy-MM-dd", "min_doc_count": 0, "extended_bounds": { "min": "2019-10-01", "max": "2019-12-31" } } } } }
interval的值可以天、周、月、季度、年等。我们可以延伸一下,比如统计今年每个季度的新发布歌曲的点赞数量
GET /music/children/_search { "size": 0, "aggs": { "sales": { "date_histogram": { "field": "releaseDate", "interval": "quarter", "format": "yyyy-MM-dd", "min_doc_count": 0, "extended_bounds": { "min": "2019-01-01", "max": "2019-12-31" } }, "aggs": { "lang_qty": { "terms": { "field": "language" }, "aggs": { "like_sum": { "sum": { "field": "likes" } } } }, "total" :{ "sum": { "field": "likes" } } } } } }
带上过滤条件
聚合查询可以和query搭配使用,相当于mysql中where与group by联合使用
查询条件
GET /music/children/_search { "size": 0, "query": { "match": { "language": "english" } }, "aggs": { "sales": { "terms": { "field": "language" } } } }
过滤条件
GET /music/children/_search { "size": 0, "query": { "constant_score": { "filter": { "term": { "language": "english" } } } }, "aggs": { "sales": { "terms": { "field": "language" } } } }
global bucket查询
global:就是global bucket,会将所有的数据纳入聚合scope,不受前面的query或filter影响。
global bucket适用于同时统计指定条件的数据与全部数据的对比,如我们创造的场景:指定作者的歌与全部歌曲的点赞数量对比。
GET /music/children/_search { "size": 0, "query": { "match": { "author": "Jean Ritchie" } }, "aggs": { "likes": { "sum": { "field": "likes" } }, "all": { "global": {}, "aggs": { "all_likes": { "sum": { "field": "likes" } } } } } }
统计近2月,近1月的点赞数
aggs.filter针对是聚合里的数据
bucket filter:对不同的bucket下的aggs,进行filter
类似于mysql的中having语法
GET /music/children/_search { "size": 0, "aggs": { "recent_60d": { "filter": { "range": { "releaseDate": { "gte": "now-60d" } } }, "aggs": { "recent_60d_likes_sum": { "sum": { "field": "likes" } } } }, "recent_30d": { "filter": { "range": { "releaseDate": { "gte": "now-30d" } } }, "aggs": { "recent_30d_likes_sum": { "avg": { "field": "likes" } } } } } }
统计排序
默认按doc_count降序排序,排序规则可以改,order里面可以指定aggs的别名,如length_avg,类似于mysql的order by cnt asc。
GET /music/children/_search { "size": 0, "aggs": { "group_by_lang": { "terms": { "field": "language", "order": { "length_avg": "desc" } }, "aggs": { "length_avg": { "avg": { "field": "length" } } } } } }
小结
本篇主要介绍常用的聚合查询,均以示例为主,了解基本写法后可以快速阅读,有不好理解的地方,多与我们熟悉的数据库查询SQL作比较,谢谢。
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。
发表评论
暂时没有评论,来抢沙发吧~