Агрегирование Histogram
Агрегирование по корзинам, основанное на источнике значений нескольких корзин, которое может применяться к числовым значениям или числовым диапазонам значений, извлечённых из документов. Оно динамически строит корзины фиксированного размера (также известные как интервалы) над значениями. Например, если документы имеют поле, содержащее цену (числовое), мы можем настроить это агрегирование так, чтобы оно динамически создавало корзины с интервалом 5 (в случае с ценой это может представлять 5 долларов). При выполнении агрегирования поле цены каждого документа будет вычисляться и будет округлено вниз до ближайшей корзины — например, если цена равна 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
}
]
}
}
} Минимальное количество документов
Вышеприведённый ответ показывает, что ни один документ не имеет цены, попадающей в диапазон [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. Вы также указываете "min_doc_count" : 0, так как хотите получить все корзины, включая пустые. Если окажется, что все продукты (документы) имеют цены выше 100, первой корзиной, которую вы получите, будет та, у которой 100 является ключом. Это вызывает путаницу, так как часто вы хотите получить и те корзины между 0 - 100.
С помощью настройки extended_bounds вы теперь можете «принудительно» заставить агрегирование гистограммы начинать создание корзин со значения min и продолжать создавать корзины до значения max (даже если документов больше нет). Использование extended_bounds имеет смысл только тогда, когда min_doc_count равно 0 (пустые корзины никогда не будут возвращены, если min_doc_count больше 0).
Обратите внимание, что (как следует из названия) extended_bounds не фильтрует корзины. Это означает, что если значение extended_bounds.min больше значений, извлечённых из документов, документы всё равно определят, какой будет первая корзина (и то же самое относится к extended_bounds.max и последней корзине). Для фильтрации корзин необходимо вложить агрегирование гистограммы в агрегирование диапазона filter с соответствующими настройками 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
}
}
}
}
} При агрегировании диапазонов корзины основаны на значениях возвращаемых документов. Это означает, что ответ может содержать корзины за пределами диапазона запроса. Например, если ваш запрос ищет значения больше 100, а у вас есть диапазон от 50 до 150 с интервалом 50, то этот документ попадет в 3 корзины — 50, 100 и 150. В общем случае лучше всего думать о шагах запроса и агрегирования как о независимых — запрос выбирает набор документов, а затем агрегирование размещает эти документы в корзинах независимо от того, как они были выбраны. См. примечание о размещении корзин по полям диапазона для получения дополнительной информации и примера.
hard_bounds — это аналог extended_bounds и может ограничить диапазон корзин в гистограмме. Это особенно полезно в случае открытых диапазонов данных, которые могут привести к очень большому количеству корзин.
Пример:
POST /sales/_search?size=0
{
"query": {
"constant_score": { "filter": { "range": { "price": { "to": "500" } } } }
},
"aggs": {
"prices": {
"histogram": {
"field": "price",
"interval": 50,
"hard_bounds": {
"min": 100,
"max": 200
}
}
}
}
} В этом примере, хотя диапазон, указанный в запросе, доходит до 500, гистограмма будет иметь только 2 корзины, начинающиеся с 100 и 150. Все остальные корзины будут опущены, даже если в результатах присутствуют документы, которые должны попасть в эти корзины.
Сортировка
По умолчанию возвращаемые корзины отсортированы по их key в порядке возрастания, хотя поведение сортировки можно контролировать с помощью настройки order. Поддерживает те же функции order, что и Terms Aggregation.
Смещение
По умолчанию ключи корзин начинаются с 0 и затем продолжаются с равномерными шагами от interval, например, если интервал равен 10, первые три корзины (предполагая, что в них есть данные) будут [0, 10), [10, 20), [20, 30). Границы корзин можно сдвинуть, используя параметр offset.
Это лучше всего иллюстрируется примером. Если есть 10 документов со значениями от 5 до 14, использование интервала 10 приведёт к двум корзинам по 5 документов в каждой. Если используется дополнительное смещение 5, то будет только одна корзина [5, 15), содержащая все 10 документов.
Формат ответа
По умолчанию корзины возвращаются в виде упорядоченного массива. Также можно запросить ответ в виде хеша, индексированного ключами корзин:
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
}
}
}
} | Документы без значения в поле |
Поля Histogram
Выполнение агрегирования Histogram над полями Histogram вычисляет общее количество подсчётов для каждого интервала.
Например, выполнение агрегирования Histogram над следующим индексом, который хранит предобработанные гистограммы с метриками задержки (в миллисекундах) для различных сетей:
PUT metrics_index/_doc/1
{
"network.name" : "net-1",
"latency_histo" : {
"values" : [1, 3, 8, 12, 15],
"counts" : [3, 7, 23, 12, 6]
}
}
PUT metrics_index/_doc/2
{
"network.name" : "net-2",
"latency_histo" : {
"values" : [1, 6, 8, 12, 14],
"counts" : [8, 17, 8, 7, 6]
}
}
POST /metrics_index/_search?size=0
{
"aggs": {
"latency_buckets": {
"histogram": {
"field": "latency_histo",
"interval": 5
}
}
}
} Агрегирование histogram суммирует количество каждого интервала, вычисленного на основе values, и возвращает следующий результат:
{
...
"aggregations": {
"prices": {
"buckets": [
{
"key": 0.0,
"doc_count": 18
},
{
"key": 5.0,
"doc_count": 48
},
{
"key": 10.0,
"doc_count": 25
},
{
"key": 15.0,
"doc_count": 6
}
]
}
}
} Агрегирование Histogram — это агрегирование по корзинам, которое распределяет документы по корзинам, а не вычисляет метрики по полям, как это делают агрегирования метрик. Каждая корзина представляет собой коллекцию документов, по которым могут выполняться под-агрегирования. С другой стороны, поле Histogram — это предобработанное поле, представляющее несколько значений в одном поле: корзины числовых данных и количество элементов/документов для каждой корзины. Это несоответствие между ожидаемым входом агрегирования Histogram (ожидаются исходные документы) и полем Histogram (которое предоставляет сводную информацию) ограничивает результат агрегирования только количеством документов для каждой корзины.
Следовательно, при выполнении агрегирования Histogram по полю Histogram под-агрегирования запрещены.
Кроме того, при выполнении агрегирования Histogram по полю Histogram параметр missing не поддерживается.
© 2023-2025 Elasticsearch
As of September 2024, Elasticsearch is available under a choice of three licenses: the Server Side Public License (SSPL), the Elastic License, or the AGPLv3 (OSI approved).
Elasticsearch and the Elasticsearch logo are trademarks of Elasticsearch B.V., registered in the U.S. and in other countries.
https://www.elastic.co/guide/en/elasticsearch/reference/7.17/search-aggregations-bucket-histogram-aggregation.html