es的聚合类型

看了本文,你将掌握

1、ES有哪些聚合类型?Bucket、Metric、Pipeline Aggregations 各自的特点是什么??

2、Bucket Aggs 有哪些种类?各自的使用场景是什么?

3、Bucket Aggs 各种类型的重要参数有哪些?注意事项是什么?

 

01 ES聚合类型简介

一图胜千言

如上图,ES的聚合一共有4种类型,Bucket 、Metric、Pipeline 是经常使用的,掌握了这3种聚合,就已经可以满足日常大部分的聚合分析场景了。

在学习之前,先掌握aggregations的语法结构:【注意aggregations关键字可使用aggs代替】

简单示例,学会agg语法:

  1.  
    GET /cars/_search
  2.  
    {
  3.  
    "size": 0,
  4.  
    "aggs": {
  5.  
    "first_agg_name": {
  6.  
    "terms": {
  7.  
    "field": "color"
  8.  
    },
  9.  
    "aggs": {
  10.  
    "sub_agg_name1": {
  11.  
    "avg": {
  12.  
    "field": "price"
  13.  
    }
  14.  
    },
  15.  
    "sub_agg_name2": {
  16.  
    "terms": {
  17.  
    "field": "make"
  18.  
    }
  19.  
    }
  20.  
    }
  21.  
    }
  22.  
    }
  23.  
    }

02 Bucket Aggregations

Bucket 就是桶的意思,即按照一定的规则将文档分配到不同的桶中,达到分类分析的目的。

ES从 2.x 到 7.x,聚合功能已经日渐强大,到 7.7 版本, Bucket 聚合已经有25种类型了,今天我们就一起系统学习 Bucket Aggregations,全面掌握 Bucket 聚合。

Bucket Aggs 概览

ps:因为篇幅问题,TeHero在文章中就只通过示例进行简单讲解,涉及其他的注意事项,重要参数等,见xmind截图,毕竟一图胜千言,哈哈,好吧,我承认,就是懒得写重复的内容【文末有xmind源文件获取方式】。

2.0 写在前面

通过上图《Bucket Aggs 概览》我们可以看到,一共有25种类型的 Bucket Aggs,对于每一种聚合类型,我们都去详细学习并掌握是比较费时间的,个人建议可以按如下方式学习:

  • 1)了解每种聚合类型的使用场景,简单而言,就是知道每种聚合是干嘛的,能对数据做怎样的分析;

  • 2)了解其注意事项和重要参数;

  • 3)完成以上2点,我觉得就差不多了,在实际工作中,面对需求,我们知道可以用哪些聚合操作解决需求即可,需要用到的时候再去详细学习具体的语法。

2.1 Terms 术语聚合

场景示例:对于博客系统,按不同的作者分类聚合,得到每位作者的博文总数

  1.  
    GET /blogs_index/_search
  2.  
    {
  3.  
    "size": 0,
  4.  
    "aggs": {
  5.  
    "author": {
  6.  
    "terms": {
  7.  
    "field": "author"
  8.  
    }
  9.  
    }
  10.  
    }
  11.  
    }

结果:

  1.  
    "aggregations" : {
  2.  
    "author" : {
  3.  
    "doc_count_error_upper_bound" : 0,
  4.  
    "sum_other_doc_count" : 0,
  5.  
    "buckets" : [
  6.  
    {
  7.  
    "key" : "方才兄",
  8.  
    "doc_count" : 3
  9.  
    },
  10.  
    {
  11.  
    "key" : "方才",
  12.  
    "doc_count" : 1
  13.  
    }
  14.  
    ]
  15.  
    }
  16.  
    }

 2.2 Rare Terms  稀有术语聚合

在 Terms Aggs 中,聚合结果的排序是默认根据 doc_count 的值降序排列,但在实际使用过程中,我们有时候希望根据 doc_count 的值升序排列,这个时候就应该使用  Rare Terms【之所以不使用 Terms aggs再去改变排序规则,是因为聚合精度问题,后续专门讨论】

场景示例:按不同的作者分类聚合,同时根据每位作者的文章总数进行升序排列

  1.  
    GET /blogs_index/_search
  2.  
    {
  3.  
    "size": 0,
  4.  
    "aggs": {
  5.  
    "author": {
  6.  
    "rare_terms": {
  7.  
    "field": "author",
  8.  
    "max_doc_count": 10
  9.  
    }
  10.  
    }
  11.  
    }
  12.  
    }

注意max_doc_count参数:术语出现的最大文档数【返回的bucket 的 doc_count <= 该值】,默认值为1,最大值为100。

结果:

  1.  
      "aggregations" : {
  2.  
    "author" : {
  3.  
    "buckets" : [
  4.  
    {
  5.  
    "key" : "方才",
  6.  
    "doc_count" : 1
  7.  
    },
  8.  
    {
  9.  
    "key" : "方才兄",
  10.  
    "doc_count" : 3
  11.  
    }
  12.  
    ]
  13.  
    }
  14.  
    }

2.3 Histogram 直方图聚合

场景示例:按商品价格区间聚合,得到不同价格区间的商品总数

  1.  
    GET /product/_search
  2.  
    {
  3.  
    "size": 0,
  4.  
    "aggs": {
  5.  
    "price": {
  6.  
    "histogram": {
  7.  
    "field": "price",
  8.  
    "interval": 2000
  9.  
    }
  10.  
    }
  11.  
    }
  12.  
    }

结果:

{
  "aggregations": {
    "price": {
      "buckets": [
        {
          "key": 0,
          "doc_count": 3
        },
        {
          "key": 20000,
          "doc_count": 4
        },
        {
          "key": 80000,
          "doc_count": 1
        }
      ]
    }
  }
}

简单解释下,返回的 “key” 值:0代表区间【0,2000),2000代表区间【2000,4000)。

2.4 Date histogram 日期直方图聚合

场景示例:查看每天博客系统的发文总数

  1.  
    GET /blogs_index/_search
  2.  
    {
  3.  
    "size": 0,
  4.  
    "aggs": {
  5.  
    "price": {
  6.  
    "date_histogram": {
  7.  
    "field": "createAt",
  8.  
    "calendar_interval": "day",
  9.  
    "format": "yyyy-MM-dd"
  10.  
    }
  11.  
    }
  12.  
    }
  13.  
    }

结果:

  1.  
    "aggregations": {
  2.  
    "price": {
  3.  
    "buckets": [
  4.  
    {
  5.  
    "key_as_string": "2020-05-22",
  6.  
    "key": 1590105600000,
  7.  
    "doc_count": 1
  8.  
    },
  9.  
    {
  10.  
    "key_as_string": "2020-05-23",
  11.  
    "key": 1590192000000,
  12.  
    "doc_count": 1
  13.  
    },
  14.  
    {
  15.  
    "key_as_string": "2020-05-24",
  16.  
    "key": 1590278400000,
  17.  
    "doc_count": 2
  18.  
    }
  19.  
    ]
  20.  
    }
  21.  
    }

2.5 Auto-interval Date Histogram 自动间隔日期直方图聚合

该聚合的应用场景,更多的可能是,页面强制需要多个点绘制图表。

场景示例:还是通过博客的创建时间做聚合,这次我希望返回3个bucket

  1.  
    GET /blogs_index/_search
  2.  
    {
  3.  
    "size": 0,
  4.  
    "aggs": {
  5.  
    "createTime": {
  6.  
    "auto_date_histogram": {
  7.  
    "field": "createAt",
  8.  
    "format": "yyyy-MM-dd",
  9.  
    "buckets": 3
  10.  
    }
  11.  
    }
  12.  
    }
  13.  
    }

结果:

  1.  
    "aggregations": {
  2.  
    "createTime": {
  3.  
    "buckets": [
  4.  
    {
  5.  
    "key_as_string": "2020-05-22",
  6.  
    "key": 1590105600000,
  7.  
    "doc_count": 1
  8.  
    },
  9.  
    {
  10.  
    "key_as_string": "2020-05-23",
  11.  
    "key": 1590192000000,
  12.  
    "doc_count": 1
  13.  
    },
  14.  
    {
  15.  
    "key_as_string": "2020-05-24",
  16.  
    "key": 1590278400000,
  17.  
    "doc_count": 2
  18.  
    }
  19.  
    ],
  20.  
    "interval": "1d"
  21.  
    }
  22.  
    }

2.6 Range 范围聚合

场景示例:查看价格在100以内,100-200和200以上 这3个范围的商品数量

  1.  
    GET /product/_search
  2.  
    {
  3.  
    "aggs": {
  4.  
    "price_ranges": {
  5.  
    "range": {
  6.  
    "field": "price",
  7.  
    "ranges": [
  8.  
    {
  9.  
    "to": 100
  10.  
    },
  11.  
    {
  12.  
    "from": 100,
  13.  
    "to": 200
  14.  
    },
  15.  
    {
  16.  
    "from": 200
  17.  
    }
  18.  
    ]
  19.  
    }
  20.  
    }
  21.  
    }
  22.  
    }

结果:

  1.  
    "aggregations": {
  2.  
    "price_ranges": {
  3.  
    "buckets": [
  4.  
    {
  5.  
    "key": "*-100.0",
  6.  
    "to": 100,
  7.  
    "doc_count": 0
  8.  
    },
  9.  
    {
  10.  
    "key": "100.0-200.0",
  11.  
    "from": 100,
  12.  
    "to": 200,
  13.  
    "doc_count": 0
  14.  
    },
  15.  
    {
  16.  
    "key": "200.0-*",
  17.  
    "from": 200,
  18.  
    "doc_count": 0
  19.  
    }
  20.  
    ]
  21.  
    }
  22.  
    }

2.7 Date Range 日期范围聚合

场景示例:获取过去到10个月之前的所有商品总数和10个月之前的商品总数:

  1.  
    GET /product/_search
  2.  
    {
  3.  
    "aggs": {
  4.  
    "range": {
  5.  
    "date_range": {
  6.  
    "field": "date",
  7.  
    "format": "yyyy-MM",
  8.  
    "ranges": [
  9.  
    {
  10.  
    "to": "now-10M/M"
  11.  
    },
  12.  
    {
  13.  
    "from": "now-10M/M"
  14.  
    }
  15.  
    ]
  16.  
    }
  17.  
    }
  18.  
    }
  19.  
    }

注意:to:date < 现在减去10个月,向下舍入到月初;from:date > = 现在减去10个月,向下舍入到月初。

结果:现在是 2020-07

  1.  
    "aggregations": {
  2.  
    "range": {
  3.  
    "buckets": [
  4.  
    {
  5.  
    "key": "*-2019-09",
  6.  
    "to": 1567296000000,
  7.  
    "to_as_string": "2019-09",
  8.  
    "doc_count": 20
  9.  
    },
  10.  
    {
  11.  
    "key": "2019-09-*",
  12.  
    "from": 1567296000000,
  13.  
    "from_as_string": "2019-09",
  14.  
    "doc_count": 50
  15.  
    }
  16.  
    ]
  17.  
    }
  18.  
    }

2.8 IP Range IP范围聚合

看个示例即可:

  1.  
    GET /ip_addresses/_search
  2.  
    {
  3.  
    "size": 10,
  4.  
    "aggs": {
  5.  
    "ip_ranges": {
  6.  
    "ip_range": {
  7.  
    "field": "ip",
  8.  
    "ranges": [
  9.  
    {
  10.  
    "to": "10.0.0.5"
  11.  
    },
  12.  
    {
  13.  
    "from": "10.0.0.5"
  14.  
    }
  15.  
    ]
  16.  
    }
  17.  
    }
  18.  
    }
  19.  
    }

结果:

  1.  
    GET /product/_search
  2.  
    {
  3.  
    "aggregations": {
  4.  
    "ip_ranges": {
  5.  
    "buckets": [
  6.  
    {
  7.  
    "key": "*-10.0.0.5",
  8.  
    "to": "10.0.0.5",
  9.  
    "doc_count": 10
  10.  
    },
  11.  
    {
  12.  
    "key": "10.0.0.5-*",
  13.  
    "from": "10.0.0.5",
  14.  
    "doc_count": 0
  15.  
    }
  16.  
    ]
  17.  
    }
  18.  
    }
  19.  
    }

2.9 Composite 复合聚合

1)对于Composite Agg 需要看两个示例,一个是翻页的示例:

  1.  
    GET /teamwork_task/_search
  2.  
    {
  3.  
    "size": 0,
  4.  
    "aggs": {
  5.  
    "my_buckets": {
  6.  
    "composite": {
  7.  
    "size": 2,
  8.  
    "sources": [
  9.  
    {
  10.  
    "customName": {
  11.  
    "terms": {
  12.  
    "field": "team_id"
  13.  
    }
  14.  
    }
  15.  
    }
  16.  
    ]
  17.  
    }
  18.  
    }
  19.  
    }
  20.  
    }

结果:

  1.  
    "aggregations": {
  2.  
    "my_buckets": {
  3.  
    "after_key": {
  4.  
    "customName": 135
  5.  
    },
  6.  
    "buckets": [
  7.  
    {
  8.  
    "key": {
  9.  
    "customName": 128
  10.  
    },
  11.  
    "doc_count": 2
  12.  
    },
  13.  
    {
  14.  
    "key": {
  15.  
    "customName": 135
  16.  
    },
  17.  
    "doc_count": 3
  18.  
    }
  19.  
    ]
  20.  
    }
  21.  
    }
  22.  
    }

翻页查询:查询 body不变,添加上次返回的 after即可

  1.  
    GET /teamwork_task/_search
  2.  
    {
  3.  
    "size": 0,
  4.  
    "aggs": {
  5.  
    "my_buckets": {
  6.  
    "composite": {
  7.  
    "size": 2,
  8.  
    "sources": [
  9.  
    {
  10.  
    "customName": {
  11.  
    "terms": {
  12.  
    "field": "team_id"
  13.  
    }
  14.  
    }
  15.  
    }
  16.  
    ],
  17.  
    "after": {
  18.  
    "customName": 135
  19.  
    }
  20.  
    }
  21.  
    }
  22.  
    }
  23.  
    }

2)问卷结果统计示例:假设有A、B两道题,每题都有2个答案,那么 Composite聚合就可以得到所有可能组合的答案的问卷数

  1.  
    GET /question_index/_search
  2.  
    {
  3.  
    "size": 0,
  4.  
    "aggs": {
  5.  
    "my_buckets": {
  6.  
    "composite": {
  7.  
    "sources": [
  8.  
    {
  9.  
    "question_A": {
  10.  
    "terms": {
  11.  
    "field": "question_A"
  12.  
    }
  13.  
    }
  14.  
    },
  15.  
    {
  16.  
    "question_B": {
  17.  
    "terms": {
  18.  
    "field": "question_B"
  19.  
    }
  20.  
    }
  21.  
    }
  22.  
    ]
  23.  
    }
  24.  
    }
  25.  
    }
  26.  
    }

结果:

  1.  
    "aggregations": {
  2.  
    "my_buckets": {
  3.  
    "after_key": {
  4.  
    "question_A": "B",
  5.  
    "question_B": 1
  6.  
    },
  7.  
    "buckets": [
  8.  
    {
  9.  
    "key": {
  10.  
    "question_A": "A",
  11.  
    "question_B": 1
  12.  
    },
  13.  
    "doc_count": 1
  14.  
    },
  15.  
    {
  16.  
    "key": {
  17.  
    "question_A": "B",
  18.  
    "question_B": 1
  19.  
    },
  20.  
    "doc_count": 1
  21.  
    }
  22.  
    ]
  23.  
    }
  24.  
    }

2.10 Filter 过滤器聚合

场景示例:只想查看商品类型是 t-shirt 的平均价格

  1.  
    POST /sales/_search?size=0
  2.  
    {
  3.  
    "aggs" : {
  4.  
    "t_shirts" : {
  5.  
    "filter" : { "term": { "type": "t-shirt" } },
  6.  
    "aggs" : {
  7.  
    "avg_price" : { "avg" : { "field" : "price" } }
  8.  
    }
  9.  
    }
  10.  
    }
  11.  
    }

ps:考虑篇幅问题,后面的例子仅写DSL,省略结果。

2.11 Filters 过滤器集合聚合

场景示例:日志统计,统计 error 和 warning 各有多少条记录

  1.  
    GET logs/_search
  2.  
    {
  3.  
    "size": 0,
  4.  
    "aggs": {
  5.  
    "messages": {
  6.  
    "filters": {
  7.  
    "filters": {
  8.  
    "errors": {
  9.  
    "match": {
  10.  
    "body": "error"
  11.  
    }
  12.  
    },
  13.  
    "warnings": {
  14.  
    "match": {
  15.  
    "body": "warning"
  16.  
    }
  17.  
    }
  18.  
    }
  19.  
    }
  20.  
    }
  21.  
    }
  22.  
    }

2.12 Global 全局聚合

场景示例:查询商品类型为 t-shirt 的商品集合及其平均价格,同时得到所有商品的平均价格

  1.  
    POST /sales/_search?size=0
  2.  
    {
  3.  
    "query": {
  4.  
    "match": {
  5.  
    "type": "t-shirt"
  6.  
    }
  7.  
    },
  8.  
    "aggs": {
  9.  
    "all_products": {
  10.  
    "global": {},
  11.  
    "aggs": {
  12.  
    "avg_price": {
  13.  
    "avg": {
  14.  
    "field": "price"
  15.  
    }
  16.  
    }
  17.  
    }
  18.  
    },
  19.  
    "t_shirts": {
  20.  
    "avg": {
  21.  
    "field": "price"
  22.  
    }
  23.  
    }
  24.  
    }
  25.  
    }

2.13 Missing 缺少聚合

场景示例:获取没有标价的商品的总数

  1.  
    POST /sales/_search?size=0
  2.  
    {
  3.  
    "aggs": {
  4.  
    "products_without_a_price": {
  5.  
    "missing": {
  6.  
    "field": "price"
  7.  
    }
  8.  
    }
  9.  
    }
  10.  
    }

2.14 Adjacency Matrix 邻接矩阵聚合

概念理解图示:

2.15 3种地理位置的bucket聚合

 2.16 后续8种bucket聚合待深入学习

posted @ 2022-07-27 14:32  方东信  阅读(1151)  评论(0编辑  收藏  举报