Агрегация по диапазонам
Многокорзинная агрегация по значению, позволяющая пользователю определить набор диапазонов — каждый из которых представляет собой корзину. В процессе агрегации значения, извлеченные из каждого документа, будут проверяться на соответствие каждому диапазону корзины, и соответствующий документ будет "помещен" в соответствующую корзину. Обратите внимание, что эта агрегация включает значение from и исключает значение to для каждого диапазона.
Пример:
GET sales/_search
{
"aggs": {
"price_ranges": {
"range": {
"field": "price",
"ranges": [
{ "to": 100.0 },
{ "from": 100.0, "to": 200.0 },
{ "from": 200.0 }
]
}
}
}
} Ответ:
{
...
"aggregations": {
"price_ranges": {
"buckets": [
{
"key": "*-100.0",
"to": 100.0,
"doc_count": 2
},
{
"key": "100.0-200.0",
"from": 100.0,
"to": 200.0,
"doc_count": 2
},
{
"key": "200.0-*",
"from": 200.0,
"doc_count": 3
}
]
}
}
} Ответ с ключами
Установка флага keyed в значение true свяжет с каждой корзиной уникальный строковый ключ и вернёт диапазоны в виде хэша, а не массива:
GET sales/_search
{
"aggs": {
"price_ranges": {
"range": {
"field": "price",
"keyed": true,
"ranges": [
{ "to": 100 },
{ "from": 100, "to": 200 },
{ "from": 200 }
]
}
}
}
} Ответ:
{
...
"aggregations": {
"price_ranges": {
"buckets": {
"*-100.0": {
"to": 100.0,
"doc_count": 2
},
"100.0-200.0": {
"from": 100.0,
"to": 200.0,
"doc_count": 2
},
"200.0-*": {
"from": 200.0,
"doc_count": 3
}
}
}
}
} Также можно настроить ключ для каждого диапазона:
GET sales/_search
{
"aggs": {
"price_ranges": {
"range": {
"field": "price",
"keyed": true,
"ranges": [
{ "key": "cheap", "to": 100 },
{ "key": "average", "from": 100, "to": 200 },
{ "key": "expensive", "from": 200 }
]
}
}
}
} Ответ:
{
...
"aggregations": {
"price_ranges": {
"buckets": {
"cheap": {
"to": 100.0,
"doc_count": 2
},
"average": {
"from": 100.0,
"to": 200.0,
"doc_count": 2
},
"expensive": {
"from": 200.0,
"doc_count": 3
}
}
}
}
} Скрипт
Если данные в ваших документах не совсем соответствуют тем данным, которые вы хотите агрегировать, используйте поле runtime. Например, если вам нужно применить определённый курс валюты:
GET sales/_search
{
"runtime_mappings": {
"price.euros": {
"type": "double",
"script": {
"source": """
emit(doc['price'].value * params.conversion_rate)
""",
"params": {
"conversion_rate": 0.835526591
}
}
}
},
"aggs": {
"price_ranges": {
"range": {
"field": "price.euros",
"ranges": [
{ "to": 100 },
{ "from": 100, "to": 200 },
{ "from": 200 }
]
}
}
}
} Вложенные агрегации
В следующем примере, не только "размещаются" документы в разные корзины, но и вычисляются статистические данные о ценах в каждом диапазоне цен.
GET sales/_search
{
"aggs": {
"price_ranges": {
"range": {
"field": "price",
"ranges": [
{ "to": 100 },
{ "from": 100, "to": 200 },
{ "from": 200 }
]
},
"aggs": {
"price_stats": {
"stats": { "field": "price" }
}
}
}
}
} Ответ:
{
...
"aggregations": {
"price_ranges": {
"buckets": [
{
"key": "*-100.0",
"to": 100.0,
"doc_count": 2,
"price_stats": {
"count": 2,
"min": 10.0,
"max": 50.0,
"avg": 30.0,
"sum": 60.0
}
},
{
"key": "100.0-200.0",
"from": 100.0,
"to": 200.0,
"doc_count": 2,
"price_stats": {
"count": 2,
"min": 150.0,
"max": 175.0,
"avg": 162.5,
"sum": 325.0
}
},
{
"key": "200.0-*",
"from": 200.0,
"doc_count": 3,
"price_stats": {
"count": 3,
"min": 200.0,
"max": 200.0,
"avg": 200.0,
"sum": 600.0
}
}
]
}
}
} Поля гистограммы
Выполнение агрегации по диапазонам над полями гистограммы вычисляет общее количество подсчётов для каждого настроенного диапазона.
Это делается без интерполяции между значениями поля гистограммы. Следовательно, возможен диапазон, который находится "между" двумя значениями гистограммы. Результирующая корзина диапазона будет иметь нулевой счётчик документов.
Вот пример, выполнение агрегации по диапазонам для следующего индекса, который хранит предварительно агрегированные гистограммы с метриками задержки (в миллисекундах) для различных сетей:
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]
}
}
GET metrics_index/_search?size=0&filter_path=aggregations
{
"aggs": {
"latency_ranges": {
"range": {
"field": "latency_histo",
"ranges": [
{"to": 2},
{"from": 2, "to": 3},
{"from": 3, "to": 10},
{"from": 10}
]
}
}
}
} Агрегация range просуммирует количество каждого диапазона, вычисленного на основе values и вернёт следующий результат:
{
"aggregations": {
"latency_ranges": {
"buckets": [
{
"key": "*-2.0",
"to": 2,
"doc_count": 11
},
{
"key": "2.0-3.0",
"from": 2,
"to": 3,
"doc_count": 0
},
{
"key": "3.0-10.0",
"from": 3,
"to": 10,
"doc_count": 55
},
{
"key": "10.0-*",
"from": 10,
"doc_count": 31
}
]
}
}
} Агрегация по диапазонам — это агрегация по корзинам, которая распределяет документы по корзинам, а не рассчитывает метрики над полями, как это делают агрегации метрик. Каждая корзина представляет собой набор документов, для которых можно запустить вложенные агрегации. С другой стороны, поле гистограммы — это предварительно агрегированное поле, представляющее собой несколько значений в одном поле: корзины числовых данных и количество элементов/документов для каждой корзины. Это несоответствие между ожидаемым вводом агрегации по диапазонам (ожидаются исходные документы) и полем гистограммы (которое предоставляет сводную информацию) ограничивает результат агрегации только количеством документов для каждой корзины.
Следовательно, при выполнении агрегации по диапазонам над полем гистограммы вложенные агрегации запрещены.
© 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-range-aggregation.html