聚合
聚合框架有助于根据搜索查询提供聚合数据。它基于称为聚合的简单构建块,这些构建块可以组成以构建复杂的数据摘要。
聚合可以看作是在一组文档上构建分析信息的工作单元。执行上下文定义此文档集是什么(例如,顶级聚合在搜索请求的已执行查询/筛选器的上下文中执行)。
聚合有许多不同的类型,每种类型都有自己的目的和输出。为了更好地理解这些类型,通常更容易将它们分为四大类:
桶聚合
构建存储桶的聚合系列,其中每个存储桶都与键和文档标准相关联。当执行聚合时,将对上下文中的每个文档评估所有bucket条件,当条件匹配时,文档将被视为“属于”相关bucket。在聚合过程结束时,我们将得到一个存储桶列表——每个存储桶都有一组属于它的文档。
度量聚合
在一组文档上跟踪和计算度量的聚合。
矩阵聚合
对多个字段进行操作并根据从请求的文档字段中提取的值生成矩阵结果的聚合系列。与度量聚合和桶聚合不同,此聚合系列尚不支持脚本编写。
管道聚合
聚合其他聚合的输出及其相关度量的聚合
接下来是有趣的部分。由于每个bucket有效地定义了一个文档集(所有属于bucket的文档),因此可以在bucket级别上关联聚合,并且这些聚合将在该bucket的上下文中执行。这就是聚合的真正威力所在:聚合可以嵌套!
注意:Bucketing聚合可以具有子聚合(Bucketing或Metric)。将为其父聚合生成的存储桶计算子聚合。嵌套聚合的级别/深度没有硬限制(可以将聚合嵌套在“父”聚合下,它本身就是另一个更高级别聚合的子聚合)。
注意:聚合对数据的双重表示进行操作。因此,当在绝对值大于2^53的多头上运行时,结果可能是近似的。
聚合结构
以下代码段捕获聚合的基本结构:
"aggregations" : {
"<aggregation_name>" : {
"<aggregation_type>" : {
<aggregation_body>
}
[,"meta" : { [<meta_data_body>] } ]?
[,"aggregations" : { [<sub_aggregation>]+ } ]?
}
[,"<aggregation_name_2>" : { ... } ]*
}
JSON中的aggregations对象(也可以使用键aggs)保存要计算的聚合。每个聚合都与用户定义的逻辑名称相关联(例如,如果聚合计算平均价格,则将其命名为avg_price是有意义的)。这些逻辑名称还将用于唯一标识响应中的聚合。每个聚合都有一个特定的类型(<aggregation_type>在上面的代码段中),通常是命名聚合体中的第一个键。根据聚合的性质,每种类型的聚合都定义自己的主体(例如,特定字段上的平均聚合将定义计算平均值的字段)。在聚合类型定义的同一级别上,可以选择定义一组附加聚合,但这仅在您定义的聚合具有bucketing性质时才有意义。在这个场景中,您在Bucketing聚合级别上定义的子聚合将针对Bucketing聚合生成的所有bucket进行计算。例如,如果在range
聚合下定义一组聚合,则将为定义的范围存储桶计算子聚合。
值
一些聚合处理从聚合文档中提取的值。通常,这些值将从使用聚合的字段键设置的特定文档字段中提取。还可以定义一个脚本来生成值(每个文档)。
为聚合配置字段和脚本设置时,脚本将被视为值脚本。虽然普通脚本是在文档级别上评估的(即,脚本可以访问与文档关联的所有数据),但值脚本是在值级别上评估的。在这种模式下,值从配置的字段中提取,脚本用于对这些值/s应用“转换”。
注意:使用脚本时,还可以定义lang和params设置。前者定义了所使用的脚本语言(假设在ElasticSearch中可以使用适当的语言,默认情况下或作为插件使用)。后者允许将脚本中的所有“动态”表达式定义为参数,从而使脚本在调用之间保持静态(这将确保在ElasticSearch中使用缓存的编译脚本)。
ElasticSearch使用映射中字段的类型来计算如何运行聚合并格式化响应。但是,在两种情况下,ElasticSearch无法找出这些信息:未映射字段(例如,在跨多个索引的搜索请求中,只有部分字段具有字段映射)和纯脚本。对于这些情况,可以使用value_type选项给elasticsearch一个提示,该选项接受以下值:string、long(适用于所有整数类型)、double(适用于所有十进制类型,如float或scalled_float)、date、ip和boolean。