Агрегация Rate
Агрегация метрик типа rate может быть использована только внутри агрегации date_histogram или composite. Она вычисляет скорость документов или поля в каждом бакете. Значения полей могут быть извлечены из конкретных числовых или полей типа гистограммы в документах.
Для агрегаций composite должно быть ровно одно date_histogram для поддержки агрегации rate.
Синтаксис
Агрегация rate в изоляции выглядит так:
{
"rate": {
"unit": "month",
"field": "requests"
}
} Следующий запрос сгруппирует все записи продаж по месяцам, а затем преобразует количество транзакций продаж в каждом бакете в годовой показатель продаж.
resp = client.search(
index="sales",
size=0,
aggs={
"by_date": {
"date_histogram": {
"field": "date",
"calendar_interval": "month"
},
"aggs": {
"my_rate": {
"rate": {
"unit": "year"
}
}
}
}
},
)
print(resp) response = client.search(
index: 'sales',
body: {
size: 0,
aggregations: {
by_date: {
date_histogram: {
field: 'date',
calendar_interval: 'month'
},
aggregations: {
my_rate: {
rate: {
unit: 'year'
}
}
}
}
}
}
)
puts response const response = await client.search({
index: "sales",
size: 0,
aggs: {
by_date: {
date_histogram: {
field: "date",
calendar_interval: "month",
},
aggs: {
my_rate: {
rate: {
unit: "year",
},
},
},
},
},
});
console.log(response); GET sales/_search
{
"size": 0,
"aggs": {
"by_date": {
"date_histogram": {
"field": "date",
"calendar_interval": "month"
},
"aggs": {
"my_rate": {
"rate": {
"unit": "year"
}
}
}
}
}
} | Гистограмма сгруппирована по месяцам. | |
| Но скорость преобразуется в годовой показатель. |
Ответ вернёт годовой показатель транзакций в каждом бакете. Так как в году 12 месяцев, годовой показатель автоматически вычисляется путём умножения месячного показателя на 12.
{
...
"aggregations" : {
"by_date" : {
"buckets" : [
{
"key_as_string" : "2015/01/01 00:00:00",
"key" : 1420070400000,
"doc_count" : 3,
"my_rate" : {
"value" : 36.0
}
},
{
"key_as_string" : "2015/02/01 00:00:00",
"key" : 1422748800000,
"doc_count" : 2,
"my_rate" : {
"value" : 24.0
}
},
{
"key_as_string" : "2015/03/01 00:00:00",
"key" : 1425168000000,
"doc_count" : 2,
"my_rate" : {
"value" : 24.0
}
}
]
}
}
} Вместо подсчёта количества документов, также можно вычислить сумму всех значений полей в документах в каждом бакете или количество значений в каждом бакете. Следующий запрос сгруппирует все записи продаж по месяцам, а затем вычислит общую месячную выручку и преобразует её в среднедневную выручку.
resp = client.search(
index="sales",
size=0,
aggs={
"by_date": {
"date_histogram": {
"field": "date",
"calendar_interval": "month"
},
"aggs": {
"avg_price": {
"rate": {
"field": "price",
"unit": "day"
}
}
}
}
},
)
print(resp) response = client.search(
index: 'sales',
body: {
size: 0,
aggregations: {
by_date: {
date_histogram: {
field: 'date',
calendar_interval: 'month'
},
aggregations: {
avg_price: {
rate: {
field: 'price',
unit: 'day'
}
}
}
}
}
}
)
puts response const response = await client.search({
index: "sales",
size: 0,
aggs: {
by_date: {
date_histogram: {
field: "date",
calendar_interval: "month",
},
aggs: {
avg_price: {
rate: {
field: "price",
unit: "day",
},
},
},
},
},
});
console.log(response); GET sales/_search
{
"size": 0,
"aggs": {
"by_date": {
"date_histogram": {
"field": "date",
"calendar_interval": "month"
},
"aggs": {
"avg_price": {
"rate": {
"field": "price",
"unit": "day"
}
}
}
}
}
} | Гистограмма сгруппирована по месяцам. | |
| Вычисляется сумма всех цен продаж | |
| Преобразуется в среднедневную выручку |
Ответ будет содержать среднедневные цены продаж для каждого месяца.
{
...
"aggregations" : {
"by_date" : {
"buckets" : [
{
"key_as_string" : "2015/01/01 00:00:00",
"key" : 1420070400000,
"doc_count" : 3,
"avg_price" : {
"value" : 17.741935483870968
}
},
{
"key_as_string" : "2015/02/01 00:00:00",
"key" : 1422748800000,
"doc_count" : 2,
"avg_price" : {
"value" : 2.142857142857143
}
},
{
"key_as_string" : "2015/03/01 00:00:00",
"key" : 1425168000000,
"doc_count" : 2,
"avg_price" : {
"value" : 12.096774193548388
}
}
]
}
}
} Также можно воспользоваться агрегациями composite для вычисления среднедневной цены продажи для каждого товара в вашем инвентаре.
resp = client.search(
index="sales",
filter_path="aggregations",
size="0",
aggs={
"buckets": {
"composite": {
"sources": [
{
"month": {
"date_histogram": {
"field": "date",
"calendar_interval": "month"
}
}
},
{
"type": {
"terms": {
"field": "type"
}
}
}
]
},
"aggs": {
"avg_price": {
"rate": {
"field": "price",
"unit": "day"
}
}
}
}
},
)
print(resp) response = client.search(
index: 'sales',
filter_path: 'aggregations',
size: 0,
body: {
aggregations: {
buckets: {
composite: {
sources: [
{
month: {
date_histogram: {
field: 'date',
calendar_interval: 'month'
}
}
},
{
type: {
terms: {
field: 'type'
}
}
}
]
},
aggregations: {
avg_price: {
rate: {
field: 'price',
unit: 'day'
}
}
}
}
}
}
)
puts response const response = await client.search({
index: "sales",
filter_path: "aggregations",
size: 0,
aggs: {
buckets: {
composite: {
sources: [
{
month: {
date_histogram: {
field: "date",
calendar_interval: "month",
},
},
},
{
type: {
terms: {
field: "type",
},
},
},
],
},
aggs: {
avg_price: {
rate: {
field: "price",
unit: "day",
},
},
},
},
},
});
console.log(response); GET sales/_search?filter_path=aggregations&size=0
{
"aggs": {
"buckets": {
"composite": {
"sources": [
{
"month": {
"date_histogram": {
"field": "date",
"calendar_interval": "month"
}
}
},
{
"type": {
"terms": {
"field": "type"
}
}
}
]
},
"aggs": {
"avg_price": {
"rate": {
"field": "price",
"unit": "day"
}
}
}
}
}
} | Композитная агрегация с источником гистограммы дат и источником для типа товара. | |
| Источник гистограммы дат группирует по месяцам | |
| Источник термов группирует по типу каждого проданного товара | |
| Вычисляется сумма всех цен продаж, в разрезе месяца и товара | |
| Преобразуется в среднедневную выручку по каждому товару |
Ответ будет содержать среднедневные цены продажи для каждого месяца по каждому товару.
{
"aggregations" : {
"buckets" : {
"after_key" : {
"month" : 1425168000000,
"type" : "t-shirt"
},
"buckets" : [
{
"key" : {
"month" : 1420070400000,
"type" : "bag"
},
"doc_count" : 1,
"avg_price" : {
"value" : 4.838709677419355
}
},
{
"key" : {
"month" : 1420070400000,
"type" : "hat"
},
"doc_count" : 1,
"avg_price" : {
"value" : 6.451612903225806
}
},
{
"key" : {
"month" : 1420070400000,
"type" : "t-shirt"
},
"doc_count" : 1,
"avg_price" : {
"value" : 6.451612903225806
}
},
{
"key" : {
"month" : 1422748800000,
"type" : "hat"
},
"doc_count" : 1,
"avg_price" : {
"value" : 1.7857142857142858
}
},
{
"key" : {
"month" : 1422748800000,
"type" : "t-shirt"
},
"doc_count" : 1,
"avg_price" : {
"value" : 0.35714285714285715
}
},
{
"key" : {
"month" : 1425168000000,
"type" : "hat"
},
"doc_count" : 1,
"avg_price" : {
"value" : 6.451612903225806
}
},
{
"key" : {
"month" : 1425168000000,
"type" : "t-shirt"
},
"doc_count" : 1,
"avg_price" : {
"value" : 5.645161290322581
}
}
]
}
}
} Добавив параметр mode со значением value_count, можно изменить вычисление со sum на количество значений поля:
resp = client.search(
index="sales",
size=0,
aggs={
"by_date": {
"date_histogram": {
"field": "date",
"calendar_interval": "month"
},
"aggs": {
"avg_number_of_sales_per_year": {
"rate": {
"field": "price",
"unit": "year",
"mode": "value_count"
}
}
}
}
},
)
print(resp) response = client.search(
index: 'sales',
body: {
size: 0,
aggregations: {
by_date: {
date_histogram: {
field: 'date',
calendar_interval: 'month'
},
aggregations: {
avg_number_of_sales_per_year: {
rate: {
field: 'price',
unit: 'year',
mode: 'value_count'
}
}
}
}
}
}
)
puts response const response = await client.search({
index: "sales",
size: 0,
aggs: {
by_date: {
date_histogram: {
field: "date",
calendar_interval: "month",
},
aggs: {
avg_number_of_sales_per_year: {
rate: {
field: "price",
unit: "year",
mode: "value_count",
},
},
},
},
},
});
console.log(response); GET sales/_search
{
"size": 0,
"aggs": {
"by_date": {
"date_histogram": {
"field": "date",
"calendar_interval": "month"
},
"aggs": {
"avg_number_of_sales_per_year": {
"rate": {
"field": "price",
"unit": "year",
"mode": "value_count"
}
}
}
}
}
} | Гистограмма сгруппирована по месяцам. | |
| Вычисляется количество всех цен продаж | |
| Преобразуется в годовое количество | |
| Изменение режима на подсчёт значений |
Ответ будет содержать среднедневные цены продаж для каждого месяца.
{
...
"aggregations" : {
"by_date" : {
"buckets" : [
{
"key_as_string" : "2015/01/01 00:00:00",
"key" : 1420070400000,
"doc_count" : 3,
"avg_number_of_sales_per_year" : {
"value" : 36.0
}
},
{
"key_as_string" : "2015/02/01 00:00:00",
"key" : 1422748800000,
"doc_count" : 2,
"avg_number_of_sales_per_year" : {
"value" : 24.0
}
},
{
"key_as_string" : "2015/03/01 00:00:00",
"key" : 1425168000000,
"doc_count" : 2,
"avg_number_of_sales_per_year" : {
"value" : 24.0
}
}
]
}
}
} По умолчанию используется режим sum.
-
"mode": "sum" - вычислить сумму всех значений поля
-
"mode": "value_count" - использовать количество значений в поле
Взаимосвязь между размерами бакетов и скоростью
Агрегация rate поддерживает все скорости, которые могут быть использованы в параметре calendar_intervals агрегации date_histogram. Указанная скорость должна быть совместима с интервалом агрегации date_histogram, т.е. должен быть возможен перевод размера бакета в скорость. По умолчанию используется интервал date_histogram.
-
"rate": "second" - совместим со всеми интервалами
-
"rate": "minute" - совместим со всеми интервалами
-
"rate": "hour" - совместим со всеми интервалами
-
"rate": "day" - совместим со всеми интервалами
-
"rate": "week" - совместим со всеми интервалами
-
"rate": "month" - совместим только с
month,quarterиyearкалендарными интервалами -
"rate": "quarter" - совместим только с
month,quarterиyearкалендарными интервалами -
"rate": "year" - совместим только с
month,quarterиyearкалендарными интервалами
Также существуют дополнительные ограничения, если гистограмма дат не является непосредственным родителем гистограммы скоростей. В этом случае, интервал скорости и интервал гистограммы должны быть в одной группе: [second, `минута`, hour, day, week] или [month, quarter, year]. Например, если гистограмма дат основана на month, поддерживаются только интервалы скорости month, quarter или year. Если гистограмма дат основана на day, поддерживаются только интервалы скорости second, `минута`, hour, day и week.
Скрипт
Если вам нужно запустить агрегацию по значениям, которые не индексированы, запустите агрегацию по полю runtime. Например, если нам нужно скорректировать цены перед расчётом скоростей:
resp = client.search(
index="sales",
size=0,
runtime_mappings={
"price.adjusted": {
"type": "double",
"script": {
"source": "emit(doc['price'].value * params.adjustment)",
"params": {
"adjustment": 0.9
}
}
}
},
aggs={
"by_date": {
"date_histogram": {
"field": "date",
"calendar_interval": "month"
},
"aggs": {
"avg_price": {
"rate": {
"field": "price.adjusted"
}
}
}
}
},
)
print(resp) response = client.search(
index: 'sales',
body: {
size: 0,
runtime_mappings: {
'price.adjusted' => {
type: 'double',
script: {
source: "emit(doc['price'].value * params.adjustment)",
params: {
adjustment: 0.9
}
}
}
},
aggregations: {
by_date: {
date_histogram: {
field: 'date',
calendar_interval: 'month'
},
aggregations: {
avg_price: {
rate: {
field: 'price.adjusted'
}
}
}
}
}
}
)
puts response const response = await client.search({
index: "sales",
size: 0,
runtime_mappings: {
"price.adjusted": {
type: "double",
script: {
source: "emit(doc['price'].value * params.adjustment)",
params: {
adjustment: 0.9,
},
},
},
},
aggs: {
by_date: {
date_histogram: {
field: "date",
calendar_interval: "month",
},
aggs: {
avg_price: {
rate: {
field: "price.adjusted",
},
},
},
},
},
});
console.log(response); GET sales/_search
{
"size": 0,
"runtime_mappings": {
"price.adjusted": {
"type": "double",
"script": {
"source": "emit(doc['price'].value * params.adjustment)",
"params": {
"adjustment": 0.9
}
}
}
},
"aggs": {
"by_date": {
"date_histogram": {
"field": "date",
"calendar_interval": "month"
},
"aggs": {
"avg_price": {
"rate": {
"field": "price.adjusted"
}
}
}
}
}
} {
...
"aggregations" : {
"by_date" : {
"buckets" : [
{
"key_as_string" : "2015/01/01 00:00:00",
"key" : 1420070400000,
"doc_count" : 3,
"avg_price" : {
"value" : 495.0
}
},
{
"key_as_string" : "2015/02/01 00:00:00",
"key" : 1422748800000,
"doc_count" : 2,
"avg_price" : {
"value" : 54.0
}
},
{
"key_as_string" : "2015/03/01 00:00:00",
"key" : 1425168000000,
"doc_count" : 2,
"avg_price" : {
"value" : 337.5
}
}
]
}
}
}
© 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/8.17/search-aggregations-metrics-rate-aggregation.html