Executing Aggregations(执行聚合)

原文链接 : https://www.elastic.co/guide/en/elasticsearch/reference/5.4/_executing_aggregations.html

译文链接 : http://www.apache.wiki/pages/viewpage.action?pageId=4260792

贡献者 : 那伊抹微笑ApacheCNApache中文网

聚合提供了从数据中分组和提取数据的能力。最简单的聚合方法大致等于 SQL GROUP BYSQL 聚合函数。在 Elasticsearch 中,您有执行搜索返回 hits(命中结果),并且同时返回聚合结果,把一个响应中的所有 hits(命中结果)分隔开的能力。这是非常强大且有效的,您可以执行查询和多个聚合,并且在一次使用中得到各自的(任何一个的)返回结果,使用一次简洁和简化的 API 来避免网络往返。

作为开始,找这个例子按 state 将所有的 account 给分组了,然后按 count 降序(默认)排序返回 top 10(默认)的 state :

  1. curl -XGET 'localhost:9200/bank/_search?pretty' -d'
  2. {
  3. "size": 0,
  4. "aggs": {
  5. "group_by_state": {
  6. "terms": {
  7. "field": "state.keyword"
  8. }
  9. }
  10. }
  11. }'

SQL 中,上面的聚合概念类似下面 :

  1. SELECT state, COUNT(*) FROM bank GROUP BY state ORDER BY COUNT(*) DESC

响应如下(部分显示):

  1. {
  2. "took": 29,
  3. "timed_out": false,
  4. "_shards": {
  5. "total": 5,
  6. "successful": 5,
  7. "failed": 0
  8. },
  9. "hits" : {
  10. "total" : 1000,
  11. "max_score" : 0.0,
  12. "hits" : [ ]
  13. },
  14. "aggregations" : {
  15. "group_by_state" : {
  16. "doc_count_error_upper_bound": 20,
  17. "sum_other_doc_count": 770,
  18. "buckets" : [ {
  19. "key" : "ID",
  20. "doc_count" : 27
  21. }, {
  22. "key" : "TX",
  23. "doc_count" : 27
  24. }, {
  25. "key" : "AL",
  26. "doc_count" : 25
  27. }, {
  28. "key" : "MD",
  29. "doc_count" : 25
  30. }, {
  31. "key" : "TN",
  32. "doc_count" : 23
  33. }, {
  34. "key" : "MA",
  35. "doc_count" : 21
  36. }, {
  37. "key" : "NC",
  38. "doc_count" : 21
  39. }, {
  40. "key" : "ND",
  41. "doc_count" : 21
  42. }, {
  43. "key" : "ME",
  44. "doc_count" : 20
  45. }, {
  46. "key" : "MO",
  47. "doc_count" : 20
  48. } ]
  49. }
  50. }
  51. }

我们可以看到上面在 IDIdaho)中有 27account(账户),接着有 27account(账户)在 TXTexas)中,25 个账户在 ALAlabama)中,等等。

注意我们设置了 size=0 以不显示搜索的 hits(命中数量),因为我们只希望在响应中看聚合结果。

基于前面的聚合,这个例子按 state 计算了平均的账户余额(再一次按 count 降序(默认)排序返回 top 10(默认)的 state ):

  1. curl -XGET 'localhost:9200/bank/_search?pretty' -d'
  2. {
  3. "size": 0,
  4. "aggs": {
  5. "group_by_state": {
  6. "terms": {
  7. "field": "state.keyword"
  8. },
  9. "aggs": {
  10. "average_balance": {
  11. "avg": {
  12. "field": "balance"
  13. }
  14. }
  15. }
  16. }
  17. }
  18. }'

注意,我们是如何内嵌 average_balance聚合到 group_by_state 聚合的内部的。这是所有聚合中常见的模式。您可以嵌入聚合到随意的聚合中以从您需要的数据中开窗汇总。

基于前面的聚合,现在让我们在 average balance(平均余额)上降序排序 :

  1. curl -XGET 'localhost:9200/bank/_search?pretty' -d'
  2. {
  3. "size": 0,
  4. "aggs": {
  5. "group_by_state": {
  6. "terms": {
  7. "field": "state.keyword",
  8. "order": {
  9. "average_balance": "desc"
  10. }
  11. },
  12. "aggs": {
  13. "average_balance": {
  14. "avg": {
  15. "field": "balance"
  16. }
  17. }
  18. }
  19. }
  20. }
  21. }'

这个例子演示了我们如何按年龄段(20-29岁,30-39岁,和 40-49岁),然后按性别,最后获得每个年龄段,每个性别的平均账户余额 :

  1. GET /bank/_search
  2. {
  3. "size": 0,
  4. "aggs": {
  5. "group_by_age": {
  6. "range": {
  7. "field": "age",
  8. "ranges": [
  9. {
  10. "from": 20,
  11. "to": 30
  12. },
  13. {
  14. "from": 30,
  15. "to": 40
  16. },
  17. {
  18. "from": 40,
  19. "to": 50
  20. }
  21. ]
  22. },
  23. "aggs": {
  24. "group_by_gender": {
  25. "terms": {
  26. "field": "gender.keyword"
  27. },
  28. "aggs": {
  29. "average_balance": {
  30. "avg": {
  31. "field": "balance"
  32. }
  33. }
  34. }
  35. }
  36. }
  37. }
  38. }
  39. }

还有一些我们这里没有细讲的其它的聚合功能。如果您想要做进一步的实验,聚合参考指南是一个比较好的起点。