# 直方图聚合(Histogram Aggregation)

A multi-bucket values source based aggregation,可以应用于从文档中提取的数值。它会动态地在值上构建固定大小（a.k.a.interval）桶。例如，如果文档有一个包含价格的字段(数值)，我们可以配置这个聚合来动态地构建带间隔5的bucket（比如价格可能代表$ 5），当聚合执行时，每个文档的价格字段将被评估，并将四舍五入到最接近的bucket，例如，如果价格是32，而bucket（桶）的大小是5，那么四舍五入将产生30，因此，文档将“掉落”到与关键30相关的bucket（桶）中，为了使这更正式，这里是使用的如下计算公式：

```
bucket_key = Math.floor((value - offset) / interval) * interval + offset
```

interval必须是正数，而offset（偏移量）必须是小数`[0, interval[`.

下面的代码片段“bucket”基于价格的间隔为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
                }
            ]
        }
    }
}
```

## Minimum document count <a href="#histogramaggregation-minimumdocumentcount" id="histogramaggregation-minimumdocumentcount"></a>

上面的结果显示，没有任何文档的价格在\[100 - 150)范围内。默认情况下，返回结果将用空桶填充直方图中的空白。由于min\_doc\_count设置，可能会更改这个和请求桶的最小值，这是由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返回数据本身范围内的所有bucket,也就是说，具有最小值(使用直方图)的文档将确定最小的bucket(带有最小键的bucket)，具有最高值的文档将确定最大的bucket(具有最高键的bucket)。通常，当请求空buckets时，这会造成混乱，特别是当数据被过滤时。

为了说明原因，让我们来看一下列子：

假设你正在过滤您的请求，以获取值在0到500之间的所有文档，此外，您还希望使用直方图来将数据切片，其中间隔为50，您还要指定“min\_doc\_count”：0，因为您希望获得所有的桶，即使是空的。如果发生这种情况，所有产品(文件)的价格都高于100，你将获得的第一个bucket将是一个100的key，这是令人困惑的，很多次，你还想把这些桶放在0到100之间。

通过使用extended\_bounds设置，现在，您可以“强制”直方图聚合来开始在特定的min值上构建bucket，并且还可以继续构建到最大值的bucket（即使没有文档了），当min\_doc\_count为0时，使用extended\_bounds才有意义（如果min\_doc\_count大于0，则永远不会返回空buckets）

注意，(顾名思义)extended\_bounds不是过滤buckets。意味着，如果extended\_bounds.min高于从文档中提取的值。这些文件仍将决定第一个bucket将是什么（对于extended\_bounds.max和最后一个bucket也是一样），对于filtering buckets，应使用适当的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
                }
            }
        }
    }
}
```

## Order <a href="#histogramaggregation-order" id="histogramaggregation-order"></a>

默认情况下，返回的bucket按它们的key升序排序，尽管顺序行为可以通过order设置来控制。

按键降序排列桶：

```
POST /sales/_search?size=0
{
    "aggs" : {
        "prices" : {
            "histogram" : {
                "field" : "price",
                "interval" : 50,
                "order" : { "_key" : "desc" }
            }
        }
    }
}
```

按其doc\_count - 升序排列：

```
POST /sales/_search?size=0
{
    "aggs" : {
        "prices" : {
            "histogram" : {
                "field" : "price",
                "interval" : 50,
                "order" : { "_count" : "asc" }
            }
        }
    }
}
```

If the histogram aggregation has a direct metrics sub-aggregation, 则后者可以确定桶的顺序：

```
POST /sales/_search?size=0
{
    "aggs" : {
        "prices" : {
            "histogram" : {
                "field" : "price",
                "interval" : 50,
                "order" : { "price_stats.min" : "asc" } #1
            },
            "aggs" : {
                "price_stats" : { "stats" : {"field" : "price"} }
            }
        }
    }
}
```

\#1 {“price\_stats.min”：asc“}将根据其price\_stats子聚合的最小值对桶进行排序。也可以根据层次结构中的“更深层次的”聚合来对buckets进行排序，只要聚合路径是single-bucket类型，就可以支持这一点，在路径中的最后一个聚合可能是单桶的，也可以是度量的。如果它是一个single-bucket类型，那么这个顺序将由bucket中的文档数来定义（例如doc\_count），如果这是一个度量标准，则与上面的规则相同（如果路径必须指出度量名称以在multi-value度量聚合的情况下排序，并且在single-value度量聚合的情况下，该排序将应用于该值）

路径必须以下列形式定义：

```
AGG_SEPARATOR       =  '>' ;
METRIC_SEPARATOR    =  '.' ;
AGG_NAME            =  <the name of the aggregation> ;
METRIC              =  <the name of the metric (in case of multi-value metrics aggregation)> ;
PATH                =  <AGG_NAME> [ <AGG_SEPARATOR>, <AGG_NAME> ]* [ <METRIC_SEPARATOR>, <METRIC> ] ;
```

```
POST /sales/_search?size=0
{
    "aggs" : {
        "prices" : {
            "histogram" : {
                "field" : "price",
                "interval" : 50,
                "order" : { "promoted_products>rating_stats.avg" : "desc" }
            },
            "aggs" : {
                "promoted_products" : {
                    "filter" : { "term" : { "promoted" : true }},
                    "aggs" : {
                        "rating_stats" : { "stats" : { "field" : "rating" }}
                    }
                }
            }
        }
    }
}
```

上述将根据促销产品的平均评级对桶进行排序

## Offset <a href="#histogramaggregation-offset" id="histogramaggregation-offset"></a>

默认情况下，bucket键以0开始，然后以interval间隔均匀分布，例如，如果间隔为10，则第一个桶（假设里面有数据）将为\[0 - 9]，\[10-19]，\[20-29]，可以使用offset选项来改变bucket的边界。

这可以用一个例子来说明，如果有10个值从5到14的文档，使用interval10将产生两个bucket，每个bucket包含5个文档，如果使用附加的offset为5，则只有一个包含所有10个文档的单个bucket\[5-14]。

## Response Format <a href="#histogramaggregation-responseformat" id="histogramaggregation-responseformat"></a>

默认情况下，buckets作为有序数组返回，还可以将响应请求为哈希，而不是用bucket键。

```
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 value <a href="#histogramaggregation-missingvalue" id="histogramaggregation-missingvalue"></a>

missing的参数定义了如何处理缺少值的文档，默认情况下，它们将被忽略，但也有可能将它们视为具有值

```
POST /sales/_search?size=0
{
    "aggs" : {
        "quantity" : {
             "histogram" : {
                 "field" : "quantity",
                 "interval": 10,
                 "missing": 0 ＃1
             }
         }
    }
}
```

＃1 quantity字段没有值的文档将落入与文档相同的bucket中 值为0


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://xiaoxiami.gitbook.io/elasticsearch/ji-chu/36aggregationsju-he-fen-679029/362tong-ju540828-bucketaggregations/zhi-fang-tu-ju-540828-histogram-aggregation.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
