大家好我是迷途,一个在互联网行业,摸爬滚打的学子。热爱学习,热爱代码,热爱技术。热爱互联网的一切。再也不怕elasticsearch系列,帅途会慢慢由浅入深,为大家剖析一遍,各位大佬请放心,虽然这个系列帅途有时候更新的有点慢,但是绝对不会烂尾!如果你喜欢本系列的话,就快点赞关注收藏安排一波吧~
前言
本文主要讲解es中的聚合查询,一般来说在es中,复杂查询,我们不会使用太多,但是在一些特定的场景下,我们就可能需要使用到。例如我们在使用es做一个大型的日志分析系统的时候(ELK),那么我们对数据的一些统计聚合等都是需要我们进行操作的,工欲善其事必先利其器,所以今天帅途就和大家一起来学习es的聚合查询吧。

正文
1、聚合的一些基本概念
-
aggs关键字
聚合关键字,优先级低,一个aggs里面可以有多个聚合,每个聚合是相互独立的,如果本次查询中有query无论确query位置在何处,我们聚合查询的都是query之后的参数
例:查询出性别为女的数据,然后求他们年龄的平均值(query优先级高于aggs)
{ "aggs" : { "avg_grade" : { "avg" : { "field" : "age" }}}, "query": { "term": { "gender": "女" }} } -
ES的4种聚合

参考官方文档:elasticsearch官方文档
-
Bucketing
桶,es的4种聚合类型之一,将满足同一种条件的数据放在一个桶中,类似于mysql中的sql中的group by 语句。与指标聚合不同,桶聚合可以包含子聚合,例如张三(数据)在地球(桶)中,同时他也属于地球之内的中国(子桶)中
-
Metric
指标(度量),指标聚合,类似于sql中的avg、sum、max等,在metric中主要有两种聚合分别是单值聚合(single-value numeric)和多值聚合(multi-value numeric)。顾名思义,单值聚合就是在本次聚合中只有一个值而多值聚合则是在聚合中有多个值
-
Matrix
矩阵,矩阵聚合,可以对多个字段进行聚合,生成数据矩阵。类似于分别使用Metric的多值聚合对数据进行聚合,目前矩阵聚合还处于测试阶段,可能后期会完全更改或者删除。并且不支持脚本
-
Pipeline
管道,管道聚合,它作用于其他聚合的结果之上,主要分为两种聚合Parent(父母)、Sibling(兄弟),管道聚合支持链路但是不能在管道聚合中在写子聚合。
Parent(父母):对父聚合处理后的数据进行处理,不会生成新的桶。在父聚合之内。
Sibling(兄弟):同级聚合,对当前同一级的聚合数据进行处理,生成新桶,必须处于多聚合之内。
2、环境准备
PostMan、ES7.X、ElasticSearch-Head
3、数据准备
这里帅途已经预先添加好了数据,我们使用head查看,数据内容与格式。有些小伙伴可能不太了解head与kibana的区别,head与kibana都是es的数据可视化工具,在日常的开发当中,可以根据我们的需求进行选择,帅途一般索引管理等用head,数据查询之类使用kibana。
我们在customer索引下准备了10条数据,他们的类型为userType,各位小伙伴注意,在es7.0之后一个index只能对应一个type,在后面可能会完全弃用。
- 准备数据

4、Bucketing聚合
-
根据性别进行分组
http://112.74.48.31:9200/customer/_search?size=0 ---GET { "aggs":{ "metoo_group":{ --自定义聚合名称 "terms":{ -- 匹配关键字 "field":"gender" --gener字段 } } } }size=0表示我们对这个查询本身查询出来的数据不感兴趣,只查看聚合后的数据
在我们执行上述代码之后,发现一个问题:Fielddata is disabled on text fields by default. Set fielddata=true on [gender] in order to load fielddata in memory by uninverting the inverted index. Note that this can however use significant memory. Alternatively use a keyword field instead.
众所周知es底层是基于lucene,默认使用倒排索引,来提升我们的查询效率,而在我们对text字段进行聚排序(sort),统计(aggs)的时候,就需要使用到FieldData(正排索引),在es5.0之后这个默认为关闭状态,因为正排索引使用的是 doc values 将数据缓存在内存当中,典型的使用空间换时间,当我们内存不够时,os会为我们将数据写入到磁盘中,甚至在我们海量的情况下会出现OOM等异常。
正排索引:将文档加载到内存(磁盘)中,从文档 Id 到文档内容、单词的关联关系,也就是说可以通过 Id获取到文档的内容。
倒排索引:将文档内容进行分词,每个分词对应文档id,如果一个分词对应了多个文档id,则生成索引矩阵。帅途这里发现一篇非常有意思的文章,对倒排索引和正排索引不太理解的同学可以去看看,参考:终于有人把Elasticsearch原理讲透了!
接下来我们手动修改index中gender字段的FieldData属性,开启正排索引,并进行分组查询。
http://112.74.48.31:9200/customer/_mapping -POST { "properties":{ "gender":{ -- 字段名称 "type":"text", -- 字段类型 修改报错 "fielddata":true --开启正排索引 } } }修改之后,我们再次调用聚合函数进行分组查询,查看返回值
{ "took": 46, "timed_out": false, "_shards": { -- 分片,不了解的同学可以去看帅途之前的博客 "total": 1, "successful": 1, "skipped": 0, "failed": 0 }, "hits": { "total": { "value": 10, "relation": "eq" }, "max_score": null, "hits": [] }, "aggregations": { "metoo_group": { -- 我们自定义的桶名 "doc_count_error_upper_bound": 0, --被遗漏的terms 可能的最大值 "sum_other_doc_count": 0, --除了返回给用户的terms,剩下的terms总数 "buckets": [ { "key": "男", "doc_count": 6 }, { "key": "女", "doc_count": 4 } ] } } } -
根据性别进行分组,分别求出平均年龄
http://112.74.48.31:9200/customer/_search?size=0 ---GET { "aggs":{ "metoo_group":{ "terms":{

本文详细介绍了Elasticsearch(ES)的聚合查询,包括基本概念、环境准备、数据准备和四种类型的聚合:Bucketing、Metric、Matrix、Pipeline。通过实例演示了如何进行桶聚合和指标聚合,解释了正排索引和倒排索引的概念。文章还探讨了Matrix聚合的现状和Pipeline聚合的两种类型。最后总结了ES聚合的关键知识点,帮助读者更好地理解和运用ES的聚合功能。

1465

被折叠的 条评论
为什么被折叠?



