统计

最后,我们还有一个需求需要完成:可以让老板在职工目录中进行统计。Elasticsearch 把这项功能称作 汇总 (aggregations),通过这个功能,我们可以针对你的数据进行复杂的统计。这个功能有些类似于 SQL 中的 GROUP BY,但是要比它更加强大。

例如,让我们找一下员工中最受欢迎的兴趣是什么:

  1. GET /megacorp/employee/_search
  2. {
  3. "aggs": {
  4. "all_interests": {
  5. "terms": { "field": "interests" }
  6. }
  7. }
  8. }

请忽略语法,让我们先来看一下结果:

  1. {
  2. ...
  3. "hits": { ... },
  4. "aggregations": {
  5. "all_interests": {
  6. "buckets": [
  7. {
  8. "key": "music",
  9. "doc_count": 2
  10. },
  11. {
  12. "key": "forestry",
  13. "doc_count": 1
  14. },
  15. {
  16. "key": "sports",
  17. "doc_count": 1
  18. }
  19. ]
  20. }
  21. }
  22. }

我们可以发现有两个员工喜欢音乐,还有一个喜欢森林,还有一个喜欢运动。这些数据并没有被预先计算好,它们是在文档被查询的同时实时计算得出的。如果你想要查询姓 Smith 的员工的兴趣汇总情况,你就可以执行如下查询:

  1. GET /megacorp/employee/_search
  2. {
  3. "query": {
  4. "match": {
  5. "last_name": "smith"
  6. }
  7. },
  8. "aggs": {
  9. "all_interests": {
  10. "terms": {
  11. "field": "interests"
  12. }
  13. }
  14. }
  15. }

这样,all_interests 的统计结果就只会包含满足查询的文档了:

  1. ...
  2. "all_interests": {
  3. "buckets": [
  4. {
  5. "key": "music",
  6. "doc_count": 2
  7. },
  8. {
  9. "key": "sports",
  10. "doc_count": 1
  11. }
  12. ]
  13. }

汇总还允许多个层面的统计。比如我们还可以统计每一个兴趣下的平均年龄:

  1. GET /megacorp/employee/_search
  2. {
  3. "aggs" : {
  4. "all_interests" : {
  5. "terms" : { "field" : "interests" },
  6. "aggs" : {
  7. "avg_age" : {
  8. "avg" : { "field" : "age" }
  9. }
  10. }
  11. }
  12. }
  13. }

虽然这次返回的汇总结果变得更加复杂了,但是它依旧很容易理解:

  1. ...
  2. "all_interests": {
  3. "buckets": [
  4. {
  5. "key": "music",
  6. "doc_count": 2,
  7. "avg_age": {
  8. "value": 28.5
  9. }
  10. },
  11. {
  12. "key": "forestry",
  13. "doc_count": 1,
  14. "avg_age": {
  15. "value": 35
  16. }
  17. },
  18. {
  19. "key": "sports",
  20. "doc_count": 1,
  21. "avg_age": {
  22. "value": 25
  23. }
  24. }
  25. ]
  26. }

在这个丰富的结果中,我们不但可以看到兴趣的统计数据,还能针对不同的兴趣来分析喜欢这个兴趣的平均年龄

即使你现在还不能很好地理解语法,但是相信你还是能发现,用这个功能来实现如此复杂的统计工作是这样的简单。你的极限取决于你存入了什么样的数据哟!