本地英文版地址: ../en/search-aggregations.html
聚合框架有助于提供基于搜索查询的聚合数据。 它基于被称为聚合(aggregations)的简单构建块,可以组合这些块来构建复杂的数据摘要。
聚合可以被看作是在一组文档上构建分析信息的工作单元。 执行的上下文定义了这个文档集是什么(例如,顶级的聚合在搜索请求的已执行的 query/filter 的上下文中执行)。
有许多不同类型的聚合,每种都有自己的目的和输出。 为了更好地理解这些类型,通常更容易将它们分为四大类:
接下来的部分才是有趣的。 由于每个桶都有效地定义了一个文档集(属于该桶的所有文档),因此可以在桶级别关联聚合,这些聚合将在该桶的上下文中执行。 这就是聚合的真正威力所在:聚合可以嵌套!
bucketing 聚合可以有子聚合(bucketing 或 metric)。 将为其父聚合生成的桶计算子聚合。 对嵌套聚合的级别/深度没有硬性限制(可以将一个聚合嵌套在一个“父”聚合下,而这个父聚合本身是另一个更高级聚合的子聚合)。
聚合在数据的 double
表示法上进行操作。
因此,在绝对值大于 2^53
的长整型数上运行时,结果可能是近似的。
构建聚合
以下代码片段体现了聚合的基本结构:
"aggregations" : { "<aggregation_name>" : { "<aggregation_type>" : { <aggregation_body> } [,"meta" : { [<meta_data_body>] } ]? [,"aggregations" : { [<sub_aggregation>]+ } ]? } [,"<aggregation_name_2>" : { ... } ]* }
JSON 中的 aggregations
对象(也可以使用 aggs
作为键)保存要计算的聚合。
每个聚合都与用户定义的逻辑名称(<aggregation_name>
)相关联(例如,如果聚合计算平均价格,则将其命名为avg_price
是有意义的)。
这些逻辑名称还将用于唯一地标识响应中的聚合。
每个聚合都有一个特定的类型(上面代码片段中的<aggregation_type>
),并且通常是命名聚合体内的第一个键。
根据聚合的性质,每种类型的聚合定义自己的主体(例如,特定字段上的 avg
聚合将定义计算平均值的字段)。
在聚合类型定义的同一级别,可以选择性的定义一组附加的聚合,但这只有在你定义的聚合具有 bucketing 性质时才有意义。
在这种情况下,将为 bucketing 聚合构建的所有桶计算在 bucketing 聚合级别定义的子聚合。
例如,如果在 range
聚合下定义了一组聚合,将为定义的范围(range)桶计算子聚合。
值的来源
一些聚合处理从聚合文档中提取的值。
通常,这些值将从指定的文档字段中提取,该字段是使用聚合的 field
键设置的。
也可以定义一个 script
来生成这些值(每个文档)。
当为聚合配置了 field
和 script
设置时,脚本将被视为value script(值脚本)
。
普通脚本在文档级别进行评估(即脚本可以访问与文档相关的所有数据),而值脚本(value script)
在value(值)级别进行评估。
在这种模式下,从已配置的 field
中提取值,并使用 script
对这些值进行“转换”。
Elasticsearch 使用映射(mapping)中的字段类型来确定如何运行聚合和格式化响应。
然而,在两种情况下,Elasticsearch 无法找出这些信息:未映射的字段(例如,在跨多个索引的搜索请求的情况下,只有其中一部分字段在映射中有定义) 和 纯脚本。
对于这些情况,可以使用 value_type
选项给 Elasticsearch 一个提示,该选项接受以下值:string
、long
(适用于所有整数类型)、double
(适用于所有十进制类型,如float
或scaled_float
)、date
、ip
和 boolean
。