1.聚合
聚合 aggregations 有助于基于搜索查询提供聚合数据。它基于称为聚合的简单构建块,可以进行组合以构建复杂的数据摘要。
聚合 aggregations 可以看作是在一组文档上建立分析信息的工作单元。执行的上下文定义此文档集是什么(例如,顶级聚合在搜索请求的已执行查询/过滤器的上下文中执行)。
有许多不同类型的聚合,每种聚合都有自己的目的和输出。为了更好地理解这些类型,通常更容易将它们分为四个主要元素:
- Bucketing
生成存储桶的一组聚合,其中每个存储桶都与一个键和一个文档条件相关联。执行聚合时,将对上下文中的每个文档评估所有存储桶条件,并且当条件匹配时,该文档将被视为“落入”相关存储桶。到聚合过程结束时,我们将得到一个存储桶列表-每个存储桶都有一组“属于”的文档。 - Metric
聚合可跟踪和计算一组文档的指标。 - Matrix
一类聚合,可在多个字段上进行操作,并根据从请求的文档字段中提取的值生成矩阵结果。与指标和存储桶聚合不同,此聚合系列尚不支持脚本。 - Pipeline
汇总其他汇总及其相关指标的输出的汇总
基于前篇文章的一个业务需求:支持管理者对员工目录做分析。允许我们基于数据生成一些精细的分析结果。聚合与 SQL 中的 GROUP BY 类似但更强大。
es中的所有模拟数据:
...
{
"_index": "megacorp",
"_type": "employee",
"_id": "3",
"_score": 1,
"_source": {
"first_name": "Douglas",
"last_name": "Fir",
"age": 35,
"about": "I like to build cabinets",
"interests": [ "forestry" ]
}
},
{
"_index": "megacorp",
"_type": "employee",
"_id": "1",
"_score": 1,
"_source": {
"first_name": "John",
"last_name": "Smith",
"age": 25,
"about": "I love to go rock climbing",
"interests": [ "sports", "music" ]
}
},
{
"_index": "megacorp",
"_type": "employee",
"_id": "2",
"_score": 1,
"_source": {
"first_name": "Jane",
"last_name": "Smith",
"age": 32,
"about": "I like to collect rock albums",
"interests": [ "music" ]
}
}
举个例子,挖掘出员工中最受欢迎的兴趣爱好:
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 属性,代表有这个兴趣爱好的所有员工的平均年龄。
即使现在不太理解这些语法也没有关系,依然很容易了解到复杂聚合及分组通过 Elasticsearch 特性实现得很完美,能够提取的数据类型也没有任何限制。