h2.post_title { background-color: rgba(43, 102, 149, 1); color: rgba(255, 255, 255, 1); font-size: 18px !important; font-weight: bold !important; line-height: 38px !important; padding-left: 10px; border-radius: 4px }

前面一直没有记录 Elasticsearch 的聚合查询或者其它复杂的查询。本篇做一下笔记,为了方便测试,索引数据依然是第五篇生成的测试索引库 db_student_test ,别名是 student_test

第一部分 基本聚合

1、最大值 max、最小值 min、平均值 avg 、总和 sum

场景:查询语文、数学、英语 这三科的最大值、最小值、平均值

  1. POST http://localhost:9200/student_test1/_search?size=0
  2. {
  3. "aggs" : {
  4. "max_chinese" : { "max" : { "field" : "chinese" } },
  5. "min_chinese" : { "min" : { "field" : "chinese" } },
  6. "avg_chinese" : { "avg" : { "field" : "chinese" } },
  7. "max_math": { "max" : { "field" : "math" } },
  8. "min_math": { "min" : { "field" : "math" } },
  9. "avg_math": { "avg" : { "field" : "math" } },
  10. "max_english": { "max" : { "field" : "english" } },
  11. "min_english": { "min" : { "field" : "english" } },
  12. "avg_english": { "avg" : { "field" : "english" } }
  13. }
  14. }

查询结果是:

  1. {
  2. "took": 0,
  3. "timed_out": false,
  4. "_shards": {
  5. "total": 1,
  6. "successful": 1,
  7. "skipped": 0,
  8. "failed": 0
  9. },
  10. "hits": {
  11. "total": {
  12. "value": 10000,
  13. "relation": "gte"
  14. },
  15. "max_score": null,
  16. "hits": []
  17. },
  18. "aggregations": {
  19. "avg_english": {
  20. "value": 57.78366490546798
  21. },
  22. "max_chinese": {
  23. "value": 98
  24. },
  25. "min_chinese": {
  26. "value": 25
  27. },
  28. "min_math": {
  29. "value": 15
  30. },
  31. "max_english": {
  32. "value": 98
  33. },
  34. "avg_chinese": {
  35. "value": 59.353859695794505
  36. },
  37. "avg_math": {
  38. "value": 56.92907568735187
  39. },
  40. "min_english": {
  41. "value": 21
  42. },
  43. "max_math": {
  44. "value": 99
  45. }
  46. }
  47. }

也可以来查询语文科目分数总和,相当于 sql 的 sum 逻辑,虽然在这里并没有什么意义:

  1. POST http://localhost:9200/student_test1/_search?size=0
  2. {
  3. "aggs" : {
  4. "sum_chinese" : { "sum" : { "field" : "chinese" } }
  5. }
  6. }

2、求个数,相当于 sql 的 count 逻辑

场景:查询所有学生总数,这里随便 count 一个 字段就可以,例如数学这个字段

  1. POST http://localhost:9200/student_test1/_search?size=0
  2. {
  3. "aggs": {
  4. "age_count": {
  5. "value_count": {
  6. "field": "math"
  7. }
  8. }
  9. }
  10. }

返回结果是:

  1. {
  2. "took": 0,
  3. "timed_out": false,
  4. "_shards": {
  5. "total": 1,
  6. "successful": 1,
  7. "skipped": 0,
  8. "failed": 0
  9. },
  10. "hits": {
  11. "total": {
  12. "value": 10000,
  13. "relation": "gte"
  14. },
  15. "max_score": null,
  16. "hits": []
  17. },
  18. "aggregations": {
  19. "age_count": {
  20. "value": 50084828
  21. }
  22. }
  23. }

课间总数是:50084828 跟第五篇我们生成的数据总量一致

3、distinct 聚合,相当于 sql  的  count ( distinct )

场景:统计语文成绩有多少种值

  1. POST http://localhost:9200/student_test1/_search?size=0
  2. {
  3. "aggs" : {
  4. "type_count" : {
  5. "cardinality" : {
  6. "field" : "chinese"
  7. }
  8. }
  9. }
  10. }

返回结果是:

  1. {
  2. "took": 0,
  3. "timed_out": false,
  4. "_shards": {
  5. "total": 1,
  6. "successful": 1,
  7. "skipped": 0,
  8. "failed": 0
  9. },
  10. "hits": {
  11. "total": {
  12. "value": 10000,
  13. "relation": "gte"
  14. },
  15. "max_score": null,
  16. "hits": []
  17. },
  18. "aggregations": {
  19. "type_count": {
  20. "value": 74
  21. }
  22. }
  23. }

从结果上看,只有74个不同的分数,与第五篇随机生成数据的规则匹配

4、统计聚合

场景:查询语文成绩 总个数、最大值、最小值、平均值、总和等

  1. POST http://localhost:9200/student_test1/_search?size=0
  2. {
  3. "aggs": {
  4. "chinese_stats": {
  5. "stats": {
  6. "field": "chinese"
  7. }
  8. }
  9. }
  10. }

返回结果是:

  1. {
  2. "took": 0,
  3. "timed_out": false,
  4. "_shards": {
  5. "total": 1,
  6. "successful": 1,
  7. "skipped": 0,
  8. "failed": 0
  9. },
  10. "hits": {
  11. "total": {
  12. "value": 10000,
  13. "relation": "gte"
  14. },
  15. "max_score": null,
  16. "hits": []
  17. },
  18. "aggregations": {
  19. "chinese_stats": {
  20. "count": 50084828,
  21. "min": 25,
  22. "max": 98,
  23. "avg": 59.353859695794505,
  24. "sum": 2972727854
  25. }
  26. }
  27. }

5、加强版统计聚合,查询结果在上面的基础上,加上方差等统计学上的数据

  1. POST http://localhost:9200/student_test1/_search?size=0
  2. {
  3. "aggs": {
  4. "chinese_stats": {
  5. "extended_stats": {
  6. "field": "chinese"
  7. }
  8. }
  9. }
  10. }

6、分位聚合统计

默认的分位是 1%  5%  25%  50%  75%  95%  99%  《= 的概念

分位数的概念:25% 的分位数是 54,意思是小于等于 54 的样本占据了总样本的 25% ,即是 54 这个数将最底层的1/4 的数据分割出来。

  1. POST http://localhost:9200/student_test1/_search?size=0
  2. {
  3. "aggs": {
  4. "chinese_percents": {
  5. "percentiles": {
  6. "field": "chinese"
  7. }
  8. }
  9. }
  10. }

也可以自定义分位:

  1. POST http://localhost:9200/student_test1/_search?size=0
  2. {
  3. "aggs": {
  4. "chinese_percents": {
  5. "percentiles": {
  6. "field": "chinese",
  7. "percents" : [10,20,30,40,50,60,70,80,90]
  8. }
  9. }
  10. }
  11. }

7、范围聚合统计

场景:分别查询语文成绩小于40分、小于50分、小于60分的比例

  1. POST http://localhost:9200/student_test1/_search?size=0
  2. {
  3. "aggs": {
  4. "gge_perc_rank": {
  5. "percentile_ranks": {
  6. "field": "chinese",
  7. "values": [40,50,60]
  8. }
  9. }
  10. }
  11. }

以上是查询成绩小于40,小于50,小于60的占比,得到的数据是: 21.29%   36.09%   51.12%  可以看到这是一个接近等差的数列,可见测试数据的随机性还是很好的。

第二部分 其它聚合方式

1、Term 聚合

场景:想知道学生的语文成绩,在所有分数值上的个数

  1. POST http://localhost:9200/student_test1/_search?size=0
  2. {
  3. "aggs" : {
  4. "genres" : {
  5. "terms" : {
  6. "field" : "chinese"
  7. }
  8. }
  9. }
  10. }

这个查询会将字段Chinese进行聚合,例如87分聚合成一个组,88分聚合成一个组,等等;

但是这里默认是按组的大小排序,而且不会将所有的组都显示出来,数量太小的组可能被忽略,查询结果如下:

  1. {
  2. "took": 1,
  3. "timed_out": false,
  4. "_shards": {
  5. "total": 1,
  6. "successful": 1,
  7. "skipped": 0,
  8. "failed": 0
  9. },
  10. "hits": {
  11. "total": {
  12. "value": 10000,
  13. "relation": "gte"
  14. },
  15. "max_score": null,
  16. "hits": []
  17. },
  18. "aggregations": {
  19. "genres": {
  20. "doc_count_error_upper_bound": 0,
  21. "sum_other_doc_count": 42560269,
  22. "buckets": [
  23. {
  24. "key": 61,
  25. "doc_count": 752863
  26. },
  27. {
  28. "key": 68,
  29. "doc_count": 752835
  30. },
  31. {
  32. "key": 55,
  33. "doc_count": 752749
  34. },
  35. {
  36. "key": 59,
  37. "doc_count": 752444
  38. },
  39. {
  40. "key": 76,
  41. "doc_count": 752405
  42. },
  43. {
  44. "key": 74,
  45. "doc_count": 752309
  46. },
  47. {
  48. "key": 56,
  49. "doc_count": 752283
  50. },
  51. {
  52. "key": 49,
  53. "doc_count": 752273
  54. },
  55. {
  56. "key": 52,
  57. "doc_count": 752201
  58. },
  59. {
  60. "key": 50,
  61. "doc_count": 752197
  62. }
  63. ]
  64. }
  65. }
  66. }

如果想要自定义筛选条件,Term聚合还可以按照以下设定来查询:

  1. post http://localhost:9200/student_test1/_search?size=0
  2. {
  3. "aggs" : {
  4. "genres" : {
  5. "terms" : {
  6. "field" : "chinese",
  7. "size" : 100, // 可能有100个不用的分数,我们将全部都展示出来
  8. "order" : { "_count" : "asc" }, // 按照组数由小到大排序
  9. "min_doc_count": 752200 //过滤条件:组数最小值是752200
  10. }
  11. }
  12. }
  13. }

查询结果是:

  1. {
  2. "took": 0,
  3. "timed_out": false,
  4. "_shards": {
  5. "total": 1,
  6. "successful": 1,
  7. "skipped": 0,
  8. "failed": 0
  9. },
  10. "hits": {
  11. "total": {
  12. "value": 10000,
  13. "relation": "gte"
  14. },
  15. "max_score": null,
  16. "hits": []
  17. },
  18. "aggregations": {
  19. "genres": {
  20. "doc_count_error_upper_bound": 0,
  21. "sum_other_doc_count": 0,
  22. "buckets": [
  23. {
  24. "key": 52,
  25. "doc_count": 752201
  26. },
  27. {
  28. "key": 49,
  29. "doc_count": 752273
  30. },
  31. {
  32. "key": 56,
  33. "doc_count": 752283
  34. },
  35. {
  36. "key": 74,
  37. "doc_count": 752309
  38. },
  39. {
  40. "key": 76,
  41. "doc_count": 752405
  42. },
  43. {
  44. "key": 59,
  45. "doc_count": 752444
  46. },
  47. {
  48. "key": 55,
  49. "doc_count": 752749
  50. },
  51. {
  52. "key": 68,
  53. "doc_count": 752835
  54. },
  55. {
  56. "key": 61,
  57. "doc_count": 752863
  58. }
  59. ]
  60. }
  61. }
  62. }

2、Filter 聚合

Filter 聚合会先进行条件过滤,在进行聚合

场景:查询华南理工大学的学生的数学科目平均分(先筛选学校,再进行分数统计聚合)

  1. {
  2. "aggs" : {
  3. "scut_math_avg" : {
  4. "filter" : { "term": { "school": "华南理工大学" } },
  5. "aggs" : {
  6. "avg_price" : { "avg" : { "field" : "math" } }
  7. }
  8. }
  9. }
  10. }

查询结果是:

  1. {
  2. "took": 0,
  3. "timed_out": false,
  4. "_shards": {
  5. "total": 1,
  6. "successful": 1,
  7. "skipped": 0,
  8. "failed": 0
  9. },
  10. "hits": {
  11. "total": {
  12. "value": 10000,
  13. "relation": "gte"
  14. },
  15. "max_score": null,
  16. "hits": []
  17. },
  18. "aggregations": {
  19. "scut_math_avg": {
  20. "doc_count": 1854993,
  21. "avg_price": {
  22. "value": 56.93080027795253
  23. }
  24. }
  25. }
  26. }

3、Filters 多重聚合

场景:查询各个学校,语文、数学、英语的平均分都是多少,可以采用多重聚合,速度可能有点慢,如下

  1. POST http://localhost:9200/student_test1/_search?size=0
  2. {
  3. "aggs" : {
  4. "messages" : {
  5. "filters" : {
  6. "filters" : {
  7. "school_1" : { "term" : { "school" : "华南理工大学" }},
  8. "school_2" : { "term" : { "school" : "中山大学" }},
  9. "school_3" : { "match" : { "school" : "暨南大学" }}
  10. }
  11. },
  12. "aggs" : {
  13. "avg_chinese" : { "avg" : { "field" : "chinese" } },
  14. "avg_math" : { "avg" : { "field" : "math" } }
  15. }
  16. }
  17. }
  18. }

于是得到结果:

  1. {
  2. "took": 0,
  3. "timed_out": false,
  4. "_shards": {
  5. "total": 1,
  6. "successful": 1,
  7. "skipped": 0,
  8. "failed": 0
  9. },
  10. "hits": {
  11. "total": {
  12. "value": 10000,
  13. "relation": "gte"
  14. },
  15. "max_score": null,
  16. "hits": []
  17. },
  18. "aggregations": {
  19. "messages": {
  20. "buckets": {
  21. "school_1": {
  22. "doc_count": 1854993,
  23. "avg_chinese": {
  24. "value": 59.353236912484306
  25. },
  26. "avg_math": {
  27. "value": 56.93080027795253
  28. }
  29. },
  30. "school_2": {
  31. "doc_count": 1855016,
  32. "avg_chinese": {
  33. "value": 59.349129064115886
  34. },
  35. "avg_math": {
  36. "value": 56.93540918245449
  37. }
  38. },
  39. "school_3": {
  40. "doc_count": 44519876,
  41. "avg_chinese": {
  42. "value": 59.35397212247402
  43. },
  44. "avg_math": {
  45. "value": 56.92948502372289
  46. }
  47. }
  48. }
  49. }
  50. }
  51. }

4、Range 范围聚合

场景:想要查询语文成绩各个分数段的人数,可以这样查询

  1. POST  http://localhost:9200/student_test1/_search?size=0
    {
  2. "aggs" : {
  3. "chinese_ranges" : {
  4. "range" : {
  5. "field" : "chinese",
  6. "ranges" : [
  7. { "to" : 60 },
  8. { "from" : 60, "to" : 75 },
  9. { "from" : 75, "to" : 85 },
  10. { "from" : 85 }
  11. ]
  12. }
  13. }
  14. }
  15. }

查询结果是:

  1. {
  2. "took": 0,
  3. "timed_out": false,
  4. "_shards": {
  5. "total": 1,
  6. "successful": 1,
  7. "skipped": 0,
  8. "failed": 0
  9. },
  10. "hits": {
  11. "total": {
  12. "value": 10000,
  13. "relation": "gte"
  14. },
  15. "max_score": null,
  16. "hits": []
  17. },
  18. "aggregations": {
  19. "chinese_ranges": {
  20. "buckets": [
  21. {
  22. "key": "*-60.0",
  23. "to": 60,
  24. "doc_count": 25096839
  25. },
  26. {
  27. "key": "60.0-75.0",
  28. "from": 60,
  29. "to": 75,
  30. "doc_count": 11278543
  31. },
  32. {
  33. "key": "75.0-85.0",
  34. "from": 75,
  35. "to": 85,
  36. "doc_count": 7424634
  37. },
  38. {
  39. "key": "85.0-*",
  40. "from": 85,
  41. "doc_count": 6284812
  42. }
  43. ]
  44. }
  45. }
  46. }

这个返回结果的组名分别是 *-60.0 60.0-75.0 75.0-85.0 85.0-*
如果我们不想要这样的组名,可以自定义组名,例如:

  1. POST http://localhost:9200/student_test1/_search?size=0
  2. {
  3. "aggs" : {
  4. "chinese_ranges" : {
  5. "range" : {
  6. "field" : "chinese",
  7. "keyed" : true,
  8. "ranges" : [
  9. { "key" : "不及格", "to" : 60 },
  10. { "key" : "及格", "from" : 60, "to" : 75 },
  11. { "key" : "良好", "from" : 75, "to" : 85 },
  12. { "key" : "优秀", "from" : 85 }
  13. ]
  14. }
  15. }
  16. }
  17. }

查询结果将会是:

  1. {
  2. "took": 1675,
  3. "timed_out": false,
  4. "_shards": {
  5. "total": 1,
  6. "successful": 1,
  7. "skipped": 0,
  8. "failed": 0
  9. },
  10. "hits": {
  11. "total": {
  12. "value": 10000,
  13. "relation": "gte"
  14. },
  15. "max_score": null,
  16. "hits": []
  17. },
  18. "aggregations": {
  19. "chinese_ranges": {
  20. "buckets": {
  21. "不及格": {
  22. "to": 60,
  23. "doc_count": 25096839
  24. },
  25. "及格": {
  26. "from": 60,
  27. "to": 75,
  28. "doc_count": 11278543
  29. },
  30. "良好": {
  31. "from": 75,
  32. "to": 85,
  33. "doc_count": 7424634
  34. },
  35. "优秀": {
  36. "from": 85,
  37. "doc_count": 6284812
  38. }
  39. }
  40. }
  41. }
  42. }

还有其它各种各样的、复杂的聚合查询,都是可以网上查资料,甚至还支持推荐系统的一些计算方法,例如矩阵的概念等等。

还可以参考 https://blog.csdn.net/alex_xfboy/article/details/86100037

Elasticsearch 第六篇:聚合统计查询的更多相关文章

  1. elasticsearch系列六:聚合分析(聚合分析简介、指标聚合、桶聚合)

    一.聚合分析简介 1. ES聚合分析是什么? 聚合分析是数据库中重要的功能特性,完成对一个查询的数据集中数据的聚合计算,如:找出某字段(或计算表达式的结果)的最大值.最小值,计算和.平均值等.ES作为 ...

  2. django 聚合统计查询

    from django.shortcuts import renderfrom django.http import HttpResponsefrom django.db.models import ...

  3. 8.3Solr API使用(StatsComponent聚合统计)

    转载请出自出处:http://eksliang.iteye.com/blog/2169134 一.概述 Solr可以利用StatsComponent 实现数据库的聚合统计查询,也就是min.max.a ...

  4. Elasticsearch 聚合统计与SQL聚合统计语法对比(一)

    Es相比关系型数据库在数据检索方面有着极大的优势,在处理亿级数据时,可谓是毫秒级响应,我们在使用Es时不仅仅进行简单的查询,有时候会做一些数据统计与分析,如果你以前是使用的关系型数据库,那么Es的数据 ...

  5. ElasticSearch入门 第九篇:实现正则表达式查询的思路

    这是ElasticSearch 2.4 版本系列的第九篇: ElasticSearch入门 第一篇:Windows下安装ElasticSearch ElasticSearch入门 第二篇:集群配置 E ...

  6. ElasticSearch入门 第六篇:复合数据类型——数组,对象和嵌套

    这是ElasticSearch 2.4 版本系列的第六篇: ElasticSearch入门 第一篇:Windows下安装ElasticSearch ElasticSearch入门 第二篇:集群配置 E ...

  7. ElasticSearch查询 第三篇:词条查询

    <ElasticSearch查询>目录导航: ElasticSearch查询 第一篇:搜索API ElasticSearch查询 第二篇:文档更新 ElasticSearch查询 第三篇: ...

  8. Elasticsearch第三篇:查询详解

    从第一篇开始,我用的ES版本就是7.8.0的,与低版本略有不同,不同点可以参考官方介绍,最大的不同就是抛弃 type 这一概念,为了方便测试,首先建立一个学生成绩的索引库(在建立的同时,规定字段类型, ...

  9. 小试牛刀ElasticSearch大数据聚合统计

    ElasticSearch相信有不少朋友都了解,即使没有了解过它那相信对ELK也有所认识E即是ElasticSearch.ElasticSearch最开始更多用于检索,作为一搜索的集群产品简单易用绝对 ...

随机推荐

  1. django rest_framework serializer的ManyRelatedField 和 SlugRelatedField使用

    class BlogListSerializer(serializers.Serializer): id = serializers.IntegerField() user = BlogUserInf ...

  2. python双向链表的实现

    python双向链表和单链表类似,只不过是增加了一个指向前面一个元素的指针,下面的代码实例了python双向链表的方法 示意图: python双向链表实现代码: # -*- coding: utf-8 ...

  3. C++ 中explicit的作用

    转载:https://www.cnblogs.com/diligenceday/p/5781408.html C++ 中explicit的作用   explicit作用: 在C++中,explicit ...

  4. SPI应用 用SPI总线读取气压传感器SCP1000的数据

    Using SPI to read a Barometric Pressure Sensor This example shows how to use the SPI (Serial Periphe ...

  5. 01 . OpenResty简介部署,优缺点,压测,适用场景及用Lua实现服务灰度发布

    简介 OpenResty 是一个基于 Nginx 与 Lua 的高性能 Web 平台,其内部集成了大量精良的 Lua 库.第三方模块以及大多数的依赖项.用于方便地搭建能够处理超高并发.扩展性极高的动态 ...

  6. HNOI 2015 【亚瑟王】

    看着洛谷里那一排任务计划,瑟瑟发抖...... 题目大意: 你有n张牌,每一张牌有一个发动的概率和造成的伤害值,游戏一共有r轮.对于每一轮游戏,你只能发动一张牌(在之前回合发动过的牌会被跳过,不予考虑 ...

  7. ORA-28001: the password has expired 密码已过期

    ORA-28001: the password has expiredORA-28001: 密码已过期 Cause:       The user's account has expired and ...

  8. 搭建ipse隧道

    我没有太多的物理服务器,实验环境只能用四台装了linux的虚拟机来模拟,用户层工具是openswan.大致拓扑如下(我有点懒,公网地址我用的194.168.10.0/24,别和192.168.xx.x ...

  9. IIS日志文件越来越大导致C盘空间变小处理方法

    问题概述 C:\inetpub\logs\LogFiles\W3SVC文件夹越来越大,IIS日志会消耗大量的硬盘空间,有潜在写满整个硬盘空间的风险,为了解决这个问题很多用户会选择关闭日志,但显然IIS ...

  10. Python中列表、元组、字典、集合与字符串,相关函数,持续更新中……

    本篇博客为博主第一次学 Python 所做的笔记(希望读者能够少点浮躁,认真阅读,平心静气学习!) 补充: 列表.元组和字符串共同属性: 属于有序序列,其中的元素有严格的先后顺序 都支持双向索引,索引 ...