# 3.6.Aggregations(聚合分析)

聚合框架有助于根据搜索查询提供聚合数据。它是基于简单的构建块也称为整合，整合就是将复杂的数据摘要有序的放在一块。

聚合可以被看做是从一组文件中获取分析信息的一系列工作的统称。聚合的实现过程就是定义这个文档集的过程（例如，在搜索请求的基础上，执行查询/过滤，才能得到高水平的聚合结果）。

现在有很多种集合，它们都有自己的目的和输出。为了加强对聚合类型的理解，通常会把这些聚类行分为三类：

## [Bucketing](https://www.elastic.co/guide/en/elasticsearch/reference/5.5/search-aggregations-bucket.html)

在众多聚合方法中，有一种叫做构建桶，它是与关键字和文档标准相关联。在执行聚合操作的过程中，文档与所有的桶标准进行匹配，如果匹配成功之后，就将这个文件放入这个桶中。在聚合操作的最后，我们将会得到一个桶列表---每个桶中有属于它的文档。

## [Metric](https://www.elastic.co/guide/en/elasticsearch/reference/5.5/search-aggregations-metrics.html)

在一组文档中跟踪和计算指标的聚合。

## [Matrix](https://www.elastic.co/guide/en/elasticsearch/reference/5.5/search-aggregations-matrix.html)

这类的聚合操作是以请求文件属性中取出值为基础，在多个属性上进行操作产生一个矩阵结果。这类的绝活不支持脚本，但是桶聚合与和度量聚合支持，这是它们的区别。

## [Pipeline](https://www.elastic.co/guide/en/elasticsearch/reference/5.5/search-aggregations-pipeline.html)

将其他的聚类方法的输出结果以及与其相连的度量进行聚合。

接下来，有趣的部分到啦。由于每个桶高效的定以一个文档集（所有的文档都属于这个桶），在桶的这一层上，文档集可以在桶内部进行高效的聚合操作。这就是聚合的力量所在：聚合可以嵌套。

> 桶集合可以子桶聚合（桶或者度量）。这个子桶聚合是在父聚合的基础之上计算出来的。在内置的桶聚合的层数或者宽度没有严格的限制（可以在一个聚合操作的下面插入一个兄弟聚合操作）。

## Structuring Aggregations

下面我们来看一下结构化聚合的主要组成部分：

```
"aggregations" : {
    "<aggregation_name>" : {
        "<aggregation_type>" : {
            <aggregation_body>
        }
        [,"meta" : {  [<meta_data_body>] } ]?
        [,"aggregations" : { [<sub_aggregation>]+ } ]?
    }
    [,"<aggregation_name_2>" : { ... } ]*
}
```

JSON中的聚合对象（可以使用关键字aggs代替）保存要计算的聚合。每一个聚合是和用户自定的一个逻辑名称相关联（例如：如果这个聚合操作是计算平均价格，就要这个逻辑名字定义为avg\_price）。在回复过程中，逻辑名称将会成为这个聚合的唯一标识。每一个聚合都有一个具体的类型（在上面的代码段中是\<aggregation\_type>，通常是指聚合题中的第一个关键字）。每种聚合根据聚合的性质（例如，特定字段上的avg聚合就是计算这个属性的平均值）来定义自身的实体。在相同层次上定义集合，可以有选择性的定义一系列聚合，它只在您自定义的聚合块中有意义。在这种情况下，在桶聚合上定义子聚合就是在所有桶上进行的一次桶聚合。例如，如果你在range聚合下面定义了一组聚合，将为定义的范围桶计算子聚合。

## Values Source

一些聚合对从聚合文档中提取的值进行处理。通常，以聚合的属性为依据，从具体的文件中提取值。也可以定义一个脚本用来生成值。

当field和script为聚合进行配置的时候，脚本被称为value script.普通的搅拌使用来评价文档（例如，这些脚本可以访问文档关联的所有数据），而值脚本是用来评价值。在这个模式下，从配置和脚本中获取的值是用来转化这些值。

> 当使用脚本的时候，可以定义lang和params进行设置。lang是定义使用什么脚本语言（假设ElasticSearch提供了正确的语言，默认情况下或作为插件）。params保证可以在脚本中定义动态的表达式作为参数，这使脚本能够在调用之间保持静态（这将确保在ElasticSearch中使用缓存的编译脚本）。

脚本可以为每一个文档产生一个或者多个值。当产生多个值的时候，可以使用script\_values\_sorted来设置生成的结果是否排序。本质上，ElasticSearch在排序方面性能非常好（例如，进行min聚合，知道要对值进行排序，ElasticSearch将跳过对所有值得迭代，并依赖列表中的第一个值作为最小值与同一文档相关联的所有其他值）。
