分析edit

终于到了最后一个业务需求:允许管理者对员工目录做分析。 Elasticsearch 有一个功能叫 聚合 (aggregations),允许我们基于数据生成一些精细的分析结果。它与 SQL 中的 GROUP BY 类似但更强大。

举个例子,找出员工中最受欢迎的兴趣爱好:

GET /megacorp/employee/_search
{
  "aggs": {
    "all_interests": {
      "terms": { "field": "interests" }
    }
  }
}

暂时忽略掉语法,直接看结果:

{
   ...
   "hits": { ... },
   "aggregations": {
      "all_interests": {
         "buckets": [
            {
               "key":       "music",
               "doc_count": 2
            },
            {
               "key":       "forestry",
               "doc_count": 1
            },
            {
               "key":       "sports",
               "doc_count": 1
            }
         ]
      }
   }
}

可以看到,两位员工对音乐感兴趣,一位对林业感兴趣,一位对运动感兴趣。 这些聚合数据并非预先统计的,而是根据当前查询匹配的文档实时生成的。 如果想知道叫 Smith 的员工中最受欢迎的兴趣爱好,只需向混合查询中添加合适的查询:

GET /megacorp/employee/_search
{
  "query": {
    "match": {
      "last_name": "smith"
    }
  },
  "aggs": {
    "all_interests": {
      "terms": {
        "field": "interests"
      }
    }
  }
}

all_interests 聚合已经变为只包含匹配查询的文档:

  ...
  "all_interests": {
     "buckets": [
        {
           "key": "music",
           "doc_count": 2
        },
        {
           "key": "sports",
           "doc_count": 1
        }
     ]
  }

聚合还支持分级汇总。比如,查询特定兴趣爱好员工的平均年龄:

GET /megacorp/employee/_search
{
    "aggs" : {
        "all_interests" : {
            "terms" : { "field" : "interests" },
            "aggs" : {
                "avg_age" : {
                    "avg" : { "field" : "age" }
                }
            }
        }
    }
}

得到的聚合结果有点儿复杂,但理解起来还是很简单的:

  ...
  "all_interests": {
     "buckets": [
        {
           "key": "music",
           "doc_count": 2,
           "avg_age": {
              "value": 28.5
           }
        },
        {
           "key": "forestry",
           "doc_count": 1,
           "avg_age": {
              "value": 35
           }
        },
        {
           "key": "sports",
           "doc_count": 1,
           "avg_age": {
              "value": 25
           }
        }
     ]
  }

输出基本是第一次聚合的加强版。依然有一个兴趣及数量的列表,只不过每个兴趣都有了一个附加的 avg_age,代表有这个兴趣爱好的所有员工的平均年龄。

即使你现在还不理解这些语法,但还是可以很容易的看到如何使用这个特性来实现复杂的聚合和分组。 能够提取的数据类型也没有任何限制。