分析

最后,我们还有一个需求需要完成:允许管理者在职员目录中进行一些分析。
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. }

该聚合结果比之前的聚合结果要更加丰富。我们依然得到了兴趣以及数量(指具有该兴趣的员工人数)的列表,但是现在每个兴趣额外拥有avg_age字段来显示具有该兴趣员工的平均年龄。

即使你还不理解语法,但你也可以大概感觉到通过这个特性可以完成相当复杂的聚合工作,你可以处理任何类型的数据。