5.2.14. Histogram Aggregation
直方图聚合
直方图聚合是一种基于多桶值源的聚合方法,可以应用于从文档中提取的数值或数值范围值上。它会动态地在这些值上建立固定大小(即间隔)的桶。例如,如果文档有一个包含 price
(数字)的字段,我们可以配置此聚合以动态构建以 5
为间隔的桶(在价格方面,它可能代表 $5)。当聚合执行时,每个文档的 price
字段将被评估并向下舍入到其最接近的桶中,例如,如果 price
为 32
,桶的大小为 5
,则舍入结果为 30
,因此该文档将「落入」与键 30
相关联的桶中。为了更正式一些,这是所使用的舍入函数:
bucket_key = Math.floor((value - offset) / interval) * interval + offset
interval
必须为正小数,而 offset
必须为 [0,interval] 中的小数(大于或等于 0 且小于 interval 的小数)。
以下示例将根据产品的 price
按间隔 50 进行分组:
POST /sales/_search?size=0
{
"aggs" : {
"prices" : {
"histogram" : {
"field" : "price",
"interval" : 50
}
}
}
}
以下是可能的响应:
{
...
"aggregations": {
"prices" : {
"buckets": [
{
"key": 0.0,
"doc_count": 1
},
{
"key": 50.0,
"doc_count": 1
},
{
"key": 100.0,
"doc_count": 0
},
{
"key": 150.0,
"doc_count": 2
},
{
"key": 200.0,
"doc_count": 3
}
]
}
}
}
最小文档数
上面的响应显示没有任何文档的 pirce
落在 [100, 150)
的范围内。默认情况下,响应将用空桶填充直方图中的空白。可以更改 min_doc_count
设置并请求具有更高最小计数的桶:
POST /sales/_search?size=0
{
"aggs" : {
"prices" : {
"histogram" : {
"field" : "price",
"interval" : 50,
"min_doc_count" : 1
}
}
}
}
响应:
{
...
"aggregations": {
"prices" : {
"buckets": [
{
"key": 0.0,
"doc_count": 1
},
{
"key": 50.0,
"doc_count": 1
},
{
"key": 150.0,
"doc_count": 2
},
{
"key": 200.0,
"doc_count": 3
}
]
}
}
}
默认情况下,histogram
返回数据本身范围内的所有桶,即具有最小值的文档(使用直方图)将确定最小桶(具有最小键的桶),具有最大值的文档将确定最大桶(具有最高键的桶)。通常,在请求空桶时,这会导致混淆,特别是当数据也被筛选时。
为了理解原因,让我们看一个例子:
假设你要过滤你的请求以获取所有值在 0
和 500
之间的文档,此外你还想使用间隔为 50
的直方图按pirce
对数据进行切片。你还可以指定 "min_doc_count" : 0
,因为你希望获得所有桶,甚至是空桶。如果碰巧所有产品(文档)的 pirce
都高于 100
,则你将获得的第一个桶将是键为 100
的桶。这很令人困惑,因为很多时候,你还希望得到那些在 0-100
之间的桶。
通过使用 extended_bounds
设置,可以「强制」直方图聚合从特定的最小值开始构建桶,一直构建到最大值(即使没有更多文档了)。当 min_doc_count
为 0 时使用 extended_bounds
设置才有意义(如果 min_doc_count
大于 0,则永远不会返回空桶)。
请注意(顾名思义),extended_bounds
不会过滤桶。这意味着,如果 extended_bounds.min
高于从文档中提取的值,那么文档仍将决定第一个桶是什么(同样的情况也适用于 extended_bounds.max
和最后一个桶)。如果想要进行桶过滤,可以将直方图聚合嵌套在带有适当的 from
/to
设置的范围过滤聚合下。
示例:
POST /sales/_search?size=0
{
"query" : {
"constant_score" : { "filter": { "range" : { "price" : { "to" : "500" } } } }
},
"aggs" : {
"prices" : {
"histogram" : {
"field" : "price",
"interval" : 50,
"extended_bounds" : {
"min" : 0,
"max" : 500
}
}
}
}
}
排序
默认情况下,返回的桶会按照它们的 key
值升序排序,不过可使用 order
设置来控制排序行为。支持与Terms Aggregation
相同的 Order
功能。
偏移量
默认情况下,桶的 key
值从 0 开始,然后以均匀步长 interval
继续分配,例如,如果间隔为 10
,则前三个桶(假设其中含有数据)将是 [0, 10)
, [10, 20)
, [20, 30)
。可以使用 offset
选项来移动桶的边界。
最好通过一个示例来说明。假如有 10 个文档,它们值范围在 5 到 14之间,如果使用间隔为10,将生成两个各包含 5 个文档的桶。如果额外使用偏移量 5,则只会生成一个包含所有 10 个文档的桶 [5, 15)
。
响应格式
默认情况下,桶以有序数组的形式返回。还可以选择以哈希形式返回响应,即按桶的键进行索引:
POST /sales/_search?size=0
{
"aggs" : {
"prices" : {
"histogram" : {
"field" : "price",
"interval" : 50,
"keyed" : true
}
}
}
}
响应:
{
...
"aggregations": {
"prices": {
"buckets": {
"0.0": {
"key": 0.0,
"doc_count": 1
},
"50.0": {
"key": 50.0,
"doc_count": 1
},
"100.0": {
"key": 100.0,
"doc_count": 0
},
"150.0": {
"key": 150.0,
"doc_count": 2
},
"200.0": {
"key": 200.0,
"doc_count": 3
}
}
}
}
}
缺失值
missing
参数用于定义当一个文档中的某些字段值缺失时该如何处理。默认情况下,它们会被忽略,但也可以将其定义为某个特定值进行处理。
POST /sales/_search?size=0
{
"aggs" : {
"quantity" : {
"histogram" : {
"field" : "quantity",
"interval": 10,
"missing": 0 ①
}
}
}
}
quantity
字段中没有值的文档与值为 0 的文档属于同一个桶。
本译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。