翼度科技»论坛 编程开发 .net 查看内容

Elasticsearch 系列(五)- 数据聚合

7

主题

7

帖子

21

积分

新手上路

Rank: 1

积分
21
本章将和大家分享 Elasticsearch 中的数据聚合功能,通过聚合(aggregations)可以实现对文档数据的统计、分析、运算。
一、数据聚合-聚合的分类

聚合(aggregations)可以实现对文档数据的统计、分析、运算。聚合的官方文档地址:https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations.html
聚合常见的有三类:
1)桶(Bucket)聚合:用来对文档做分组

  • TermAggregation:按照文档字段值分组
  • Date Histogram:按照日期阶梯分组,例如:一周为一组,或者一月为一组。
2)度量(Metric)聚合:用于计算一些值,比如:最大值、最小值、平均值等。

  • Avg:求平均值
  • Max:求最大值
  • Min:求最小值
  • Stats:同时求max、min、avg、sum等。
3)管道(Pipeline)聚合:以其它聚合的结果为基础做聚合。
总结:
1)什么是聚合?

  • 聚合是对文档数据的统计、分析、计算
2)聚合的常见种类有哪些?

  • Bucket:对文档数据分组,并统计每组数量
  • Metric:对文档数据做计算,例如:avg
  • Pipeline:基于其它聚合结果再做聚合
3)参与聚合的字段类型不能是 text(可分词的文本)类型,可以是:keyword、数值、日期、布尔类型。
二、数据聚合-DSL实现Bucket聚合

1、DSL实现Bucket聚合

现在,我们要统计所有数据中的酒店品牌有几种,此时可以根据酒店品牌的名称做聚合。
类型为term类型,DSL示例:
  1. # 聚合功能
  2. GET /hotel/_search
  3. {
  4.   "size": 0, //设置size为0,结果中不包含文档,只包含聚合结果
  5.   "aggs": { //定义聚合
  6.     "brandAgg": { //给聚合起个名字
  7.       "terms": { //聚合的类型,按照品牌值聚合,所以选择term
  8.         "field": "brand", //参与聚合的字段
  9.         "size": 10 //希望获取的聚合结果数量
  10.       }
  11.     }
  12.   }
  13. }
复制代码
运行结果如下:
  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" : 201,
  13.       "relation" : "eq"
  14.     },
  15.     "max_score" : null,
  16.     "hits" : [ ]
  17.   },
  18.   "aggregations" : {
  19.     "brandAgg" : {
  20.       "doc_count_error_upper_bound" : 0,
  21.       "sum_other_doc_count" : 39,
  22.       "buckets" : [
  23.         {
  24.           "key" : "7天酒店",
  25.           "doc_count" : 30
  26.         },
  27.         {
  28.           "key" : "如家",
  29.           "doc_count" : 30
  30.         },
  31.         {
  32.           "key" : "皇冠假日",
  33.           "doc_count" : 17
  34.         },
  35.         {
  36.           "key" : "速8",
  37.           "doc_count" : 15
  38.         },
  39.         {
  40.           "key" : "万怡",
  41.           "doc_count" : 13
  42.         },
  43.         {
  44.           "key" : "华美达",
  45.           "doc_count" : 13
  46.         },
  47.         {
  48.           "key" : "和颐",
  49.           "doc_count" : 12
  50.         },
  51.         {
  52.           "key" : "万豪",
  53.           "doc_count" : 11
  54.         },
  55.         {
  56.           "key" : "喜来登",
  57.           "doc_count" : 11
  58.         },
  59.         {
  60.           "key" : "希尔顿",
  61.           "doc_count" : 10
  62.         }
  63.       ]
  64.     }
  65.   }
  66. }
复制代码
2、Bucket聚合-聚合结果排序

默认情况下,Bucket聚合会统计Bucket内的文档数量,记为_count,并且按照_count降序排序。
我们可以修改结果排序方式:
  1. # 聚合功能,自定义排序规则
  2. GET /hotel/_search
  3. {
  4.   "size": 0,
  5.   "aggs": {
  6.     "brandAgg": {
  7.       "terms": {
  8.         "field": "brand",
  9.         "size": 10,
  10.         "order": {
  11.           "_count": "asc" //按照_count升序排列
  12.         }
  13.       }
  14.     }
  15.   }
  16. }
复制代码
运行结果如下:
  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" : 201,
  13.       "relation" : "eq"
  14.     },
  15.     "max_score" : null,
  16.     "hits" : [ ]
  17.   },
  18.   "aggregations" : {
  19.     "brandAgg" : {
  20.       "doc_count_error_upper_bound" : 0,
  21.       "sum_other_doc_count" : 130,
  22.       "buckets" : [
  23.         {
  24.           "key" : "万丽",
  25.           "doc_count" : 2
  26.         },
  27.         {
  28.           "key" : "丽笙",
  29.           "doc_count" : 2
  30.         },
  31.         {
  32.           "key" : "君悦",
  33.           "doc_count" : 4
  34.         },
  35.         {
  36.           "key" : "豪生",
  37.           "doc_count" : 6
  38.         },
  39.         {
  40.           "key" : "维也纳",
  41.           "doc_count" : 7
  42.         },
  43.         {
  44.           "key" : "凯悦",
  45.           "doc_count" : 8
  46.         },
  47.         {
  48.           "key" : "希尔顿",
  49.           "doc_count" : 10
  50.         },
  51.         {
  52.           "key" : "汉庭",
  53.           "doc_count" : 10
  54.         },
  55.         {
  56.           "key" : "万豪",
  57.           "doc_count" : 11
  58.         },
  59.         {
  60.           "key" : "喜来登",
  61.           "doc_count" : 11
  62.         }
  63.       ]
  64.     }
  65.   }
  66. }
复制代码
3、Bucket聚合-限定聚合范围

默认情况下,Bucket聚合是对索引库的所有文档做聚合,我们可以限定要聚合的文档范围,只要添加query条件即可。
示例:
  1. # 聚合功能,限定聚合范围
  2. GET /hotel/_search
  3. {
  4.   "query": {
  5.     "range": {
  6.       "price": {
  7.         "lte": 200 //只对200元以下的文档聚合
  8.       }
  9.     }
  10.   },
  11.   "size": 0,
  12.   "aggs": {
  13.     "brandAgg": {
  14.       "terms": {
  15.         "field": "brand",
  16.         "size": 10,
  17.         "order": {
  18.           "_count": "asc"
  19.         }
  20.       }
  21.     }
  22.   }
  23. }
复制代码
运行结果如下:
  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" : 17,
  13.       "relation" : "eq"
  14.     },
  15.     "max_score" : null,
  16.     "hits" : [ ]
  17.   },
  18.   "aggregations" : {
  19.     "brandAgg" : {
  20.       "doc_count_error_upper_bound" : 0,
  21.       "sum_other_doc_count" : 0,
  22.       "buckets" : [
  23.         {
  24.           "key" : "7天酒店",
  25.           "doc_count" : 1
  26.         },
  27.         {
  28.           "key" : "汉庭",
  29.           "doc_count" : 1
  30.         },
  31.         {
  32.           "key" : "速8",
  33.           "doc_count" : 2
  34.         },
  35.         {
  36.           "key" : "如家",
  37.           "doc_count" : 13
  38.         }
  39.       ]
  40.     }
  41.   }
  42. }
复制代码
4、总结

1)aggs代表聚合,与query同级,此时query的作用是?

  • 限定聚合的的文档范围
2)聚合必须的三要素是什么?

  • 聚合名称
  • 聚合类型
  • 聚合字段
3)聚合可配置属性有哪些?

  • size:指定聚合结果数量
  • order:指定聚合结果排序方式
  • field:指定聚合字段
三、数据聚合-DSL实现Metric聚合

例如:我们要求获取每个品牌的用户评分的min、max、avg等值。
我们可以利用stats聚合:
  1. # 嵌套聚合Metric
  2. GET /hotel/_search
  3. {
  4.   "size": 0,
  5.   "aggs": {
  6.     "brandAgg": {
  7.       "terms": {
  8.         "field": "brand",
  9.         "size": 10,
  10.         "order": {
  11.           "scoreAgg.avg": "desc" //对桶里面的数据做排序
  12.         }
  13.       },
  14.       "aggs": { //是brandAgg聚合的子聚合,也就是分组后对每组分别计算
  15.         "scoreAgg": { //聚合名称
  16.           "stats": { //聚合类型,这里stats可以计算min、max、avg等
  17.             "field": "score" //聚合字段,这里是score
  18.           }
  19.         }
  20.       }
  21.     }
  22.   }
  23. }
复制代码
运行结果如下所示:
  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" : 201,
  13.       "relation" : "eq"
  14.     },
  15.     "max_score" : null,
  16.     "hits" : [ ]
  17.   },
  18.   "aggregations" : {
  19.     "brandAgg" : {
  20.       "doc_count_error_upper_bound" : 0,
  21.       "sum_other_doc_count" : 111,
  22.       "buckets" : [
  23.         {
  24.           "key" : "万丽",
  25.           "doc_count" : 2,
  26.           "scoreAgg" : {
  27.             "count" : 2,
  28.             "min" : 46.0,
  29.             "max" : 47.0,
  30.             "avg" : 46.5,
  31.             "sum" : 93.0
  32.           }
  33.         },
  34.         {
  35.           "key" : "凯悦",
  36.           "doc_count" : 8,
  37.           "scoreAgg" : {
  38.             "count" : 8,
  39.             "min" : 45.0,
  40.             "max" : 47.0,
  41.             "avg" : 46.25,
  42.             "sum" : 370.0
  43.           }
  44.         },
  45.         {
  46.           "key" : "和颐",
  47.           "doc_count" : 12,
  48.           "scoreAgg" : {
  49.             "count" : 12,
  50.             "min" : 44.0,
  51.             "max" : 47.0,
  52.             "avg" : 46.083333333333336,
  53.             "sum" : 553.0
  54.           }
  55.         },
  56.         {
  57.           "key" : "丽笙",
  58.           "doc_count" : 2,
  59.           "scoreAgg" : {
  60.             "count" : 2,
  61.             "min" : 46.0,
  62.             "max" : 46.0,
  63.             "avg" : 46.0,
  64.             "sum" : 92.0
  65.           }
  66.         },
  67.         {
  68.           "key" : "喜来登",
  69.           "doc_count" : 11,
  70.           "scoreAgg" : {
  71.             "count" : 11,
  72.             "min" : 44.0,
  73.             "max" : 48.0,
  74.             "avg" : 46.0,
  75.             "sum" : 506.0
  76.           }
  77.         },
  78.         {
  79.           "key" : "皇冠假日",
  80.           "doc_count" : 17,
  81.           "scoreAgg" : {
  82.             "count" : 17,
  83.             "min" : 44.0,
  84.             "max" : 48.0,
  85.             "avg" : 46.0,
  86.             "sum" : 782.0
  87.           }
  88.         },
  89.         {
  90.           "key" : "万豪",
  91.           "doc_count" : 11,
  92.           "scoreAgg" : {
  93.             "count" : 11,
  94.             "min" : 43.0,
  95.             "max" : 47.0,
  96.             "avg" : 45.81818181818182,
  97.             "sum" : 504.0
  98.           }
  99.         },
  100.         {
  101.           "key" : "万怡",
  102.           "doc_count" : 13,
  103.           "scoreAgg" : {
  104.             "count" : 13,
  105.             "min" : 44.0,
  106.             "max" : 48.0,
  107.             "avg" : 45.69230769230769,
  108.             "sum" : 594.0
  109.           }
  110.         },
  111.         {
  112.           "key" : "君悦",
  113.           "doc_count" : 4,
  114.           "scoreAgg" : {
  115.             "count" : 4,
  116.             "min" : 44.0,
  117.             "max" : 47.0,
  118.             "avg" : 45.5,
  119.             "sum" : 182.0
  120.           }
  121.         },
  122.         {
  123.           "key" : "希尔顿",
  124.           "doc_count" : 10,
  125.           "scoreAgg" : {
  126.             "count" : 10,
  127.             "min" : 37.0,
  128.             "max" : 48.0,
  129.             "avg" : 45.4,
  130.             "sum" : 454.0
  131.           }
  132.         }
  133.       ]
  134.     }
  135.   }
  136. }
复制代码
四、数据聚合-多条件聚合

需求:搜索页面中的城市、星级、品牌等信息不应该是在页面写死,而是通过聚合索引库中的酒店数据得来的。

示例:
  1. # 多条件聚合
  2. GET /hotel/_search
  3. {
  4.   "query": {
  5.     "bool": {
  6.       "must": [
  7.         {
  8.           "match": {
  9.             "all": "酒店"
  10.           }
  11.         }
  12.       ],
  13.       "should": [
  14.         {
  15.           "term": {
  16.             "brand": "皇冠假日"
  17.           }
  18.         },
  19.         {
  20.           "term": {
  21.             "brand": "华美达"
  22.           }
  23.         }
  24.       ],
  25.       "must_not": [
  26.         {
  27.           "range": {
  28.             "price": {
  29.               "lte": 500
  30.             }
  31.           }
  32.         }
  33.       ],
  34.       "filter": [
  35.         {
  36.           "range": {
  37.             "score": {
  38.               "gte": 45
  39.             }
  40.           }
  41.         }
  42.       ],
  43.       "minimum_should_match": 1,
  44.       "boost": 1
  45.     }
  46.   },
  47.   "size": 0,
  48.   "aggs": {
  49.     "cityAgg": {
  50.       "terms": {
  51.         "field": "city",
  52.         "size": 10,
  53.         "order": {
  54.           "_count": "desc"
  55.         }
  56.       }
  57.     },
  58.     "starNameAgg": {
  59.       "terms": {
  60.         "field": "starName",
  61.         "size": 10,
  62.         "order": {
  63.           "_count": "desc"
  64.         }
  65.       }
  66.     },
  67.     "brandAgg": {
  68.       "terms": {
  69.         "field": "brand",
  70.         "size": 10,
  71.         "order": {
  72.           "scoreAgg.avg": "desc"
  73.         }
  74.       },
  75.       "aggs": {
  76.         "scoreAgg": {
  77.           "stats": {
  78.             "field": "score"
  79.           }
  80.         }
  81.       }
  82.     }
  83.   }
  84. }
复制代码
运行结果如下:
  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" : 17,
  13.       "relation" : "eq"
  14.     },
  15.     "max_score" : null,
  16.     "hits" : [ ]
  17.   },
  18.   "aggregations" : {
  19.     "brandAgg" : {
  20.       "doc_count_error_upper_bound" : 0,
  21.       "sum_other_doc_count" : 0,
  22.       "buckets" : [
  23.         {
  24.           "key" : "皇冠假日",
  25.           "doc_count" : 12,
  26.           "scoreAgg" : {
  27.             "count" : 12,
  28.             "min" : 45.0,
  29.             "max" : 48.0,
  30.             "avg" : 46.416666666666664,
  31.             "sum" : 557.0
  32.           }
  33.         },
  34.         {
  35.           "key" : "华美达",
  36.           "doc_count" : 5,
  37.           "scoreAgg" : {
  38.             "count" : 5,
  39.             "min" : 45.0,
  40.             "max" : 46.0,
  41.             "avg" : 45.2,
  42.             "sum" : 226.0
  43.           }
  44.         }
  45.       ]
  46.     },
  47.     "starNameAgg" : {
  48.       "doc_count_error_upper_bound" : 0,
  49.       "sum_other_doc_count" : 0,
  50.       "buckets" : [
  51.         {
  52.           "key" : "五钻",
  53.           "doc_count" : 7
  54.         },
  55.         {
  56.           "key" : "五星级",
  57.           "doc_count" : 5
  58.         },
  59.         {
  60.           "key" : "四星级",
  61.           "doc_count" : 3
  62.         },
  63.         {
  64.           "key" : "四钻",
  65.           "doc_count" : 2
  66.         }
  67.       ]
  68.     },
  69.     "cityAgg" : {
  70.       "doc_count_error_upper_bound" : 0,
  71.       "sum_other_doc_count" : 0,
  72.       "buckets" : [
  73.         {
  74.           "key" : "上海",
  75.           "doc_count" : 10
  76.         },
  77.         {
  78.           "key" : "北京",
  79.           "doc_count" : 4
  80.         },
  81.         {
  82.           "key" : "深圳",
  83.           "doc_count" : 3
  84.         }
  85.       ]
  86.     }
  87.   }
  88. }
复制代码
至此本文就全部介绍完了,如果觉得对您有所启发请记得点个赞哦!!!
 
此文由博主精心撰写转载请保留此原文链接:https://www.cnblogs.com/xyh9039/p/18093166
版权声明:如有雷同纯属巧合,如有侵权请及时联系本人修改,谢谢!!!

来源:https://www.cnblogs.com/xyh9039/p/18093166
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x

举报 回复 使用道具