Агрегация Top metrics
Агрегация top_metrics выбирает метрики из документа с наибольшим или наименьшим значением "сортировки". Например, это получает значение поля m в документе с наибольшим значением s:
resp = client.bulk(
index="test",
refresh=True,
operations=[
{
"index": {}
},
{
"s": 1,
"m": 3.1415
},
{
"index": {}
},
{
"s": 2,
"m": 1
},
{
"index": {}
},
{
"s": 3,
"m": 2.71828
}
],
)
print(resp)
resp1 = client.search(
index="test",
filter_path="aggregations",
aggs={
"tm": {
"top_metrics": {
"metrics": {
"field": "m"
},
"sort": {
"s": "desc"
}
}
}
},
)
print(resp1) response = client.bulk(
index: 'test',
refresh: true,
body: [
{
index: {}
},
{
s: 1,
m: 3.1415
},
{
index: {}
},
{
s: 2,
m: 1
},
{
index: {}
},
{
s: 3,
m: 2.71828
}
]
)
puts response
response = client.search(
index: 'test',
filter_path: 'aggregations',
body: {
aggregations: {
tm: {
top_metrics: {
metrics: {
field: 'm'
},
sort: {
s: 'desc'
}
}
}
}
}
)
puts response const response = await client.bulk({
index: "test",
refresh: "true",
operations: [
{
index: {},
},
{
s: 1,
m: 3.1415,
},
{
index: {},
},
{
s: 2,
m: 1,
},
{
index: {},
},
{
s: 3,
m: 2.71828,
},
],
});
console.log(response);
const response1 = await client.search({
index: "test",
filter_path: "aggregations",
aggs: {
tm: {
top_metrics: {
metrics: {
field: "m",
},
sort: {
s: "desc",
},
},
},
},
});
console.log(response1); POST /test/_bulk?refresh
{"index": {}}
{"s": 1, "m": 3.1415}
{"index": {}}
{"s": 2, "m": 1.0}
{"index": {}}
{"s": 3, "m": 2.71828}
POST /test/_search?filter_path=aggregations
{
"aggs": {
"tm": {
"top_metrics": {
"metrics": {"field": "m"},
"sort": {"s": "desc"}
}
}
}
} Что возвращает:
{
"aggregations": {
"tm": {
"top": [ {"sort": [3], "metrics": {"m": 2.718280076980591 } } ]
}
}
} Агрегация top_metrics довольно похожа по духу на top_hits, но, поскольку она более ограничена, она может выполнять свою работу с меньшим объёмом памяти и часто быстрее.
sort
Поле sort в запросе метрики работает точно так же, как поле sort в запросе поиска, за исключением:
- Оно не может использоваться с полями бинарного, уплощенного, IP, ключевого или текстового типа.
- Оно поддерживает только одно значение сортировки, поэтому порядок документов при равенстве не определяется.
Метрики, возвращаемые агрегацией, — это первый результат, который бы вернул запрос поиска. Поэтому,
-
"sort": {"s": "desc"} - получает метрики из документа с наибольшим значением
s -
"sort": {"s": "asc"} - получает метрики из документа с наименьшим значением
s -
"sort": {"_geo_distance": {"location": "POINT (-78.6382 35.7796)"}} - получает метрики из документов с значением
locationближайшим к35.7796, -78.6382 -
"sort": "_score" - получает метрики из документа с наивысшим баллом
metrics
metrics выбирает поля "верхнего" документа для возврата. Вы можете запросить одну метрику, используя что-то вроде "metrics": {"field": "m"}, или несколько метрик, запросив список метрик, как в "metrics": [{"field": "m"}, {"field": "i"}.
metrics.field поддерживает следующие типы полей:
За исключением ключевых слов, также поддерживаются временные поля соответствующих типов. metrics.field не поддерживает поля с массивами. Агрегация top_metric по массивам может возвращать несогласованные результаты.
В следующем примере выполняется агрегация top_metrics по нескольким типам полей.
resp = client.indices.create(
index="test",
mappings={
"properties": {
"d": {
"type": "date"
}
}
},
)
print(resp)
resp1 = client.bulk(
index="test",
refresh=True,
operations=[
{
"index": {}
},
{
"s": 1,
"m": 3.1415,
"i": 1,
"d": "2020-01-01T00:12:12Z",
"t": "cat"
},
{
"index": {}
},
{
"s": 2,
"m": 1,
"i": 6,
"d": "2020-01-02T00:12:12Z",
"t": "dog"
},
{
"index": {}
},
{
"s": 3,
"m": 2.71828,
"i": -12,
"d": "2019-12-31T00:12:12Z",
"t": "chicken"
}
],
)
print(resp1)
resp2 = client.search(
index="test",
filter_path="aggregations",
aggs={
"tm": {
"top_metrics": {
"metrics": [
{
"field": "m"
},
{
"field": "i"
},
{
"field": "d"
},
{
"field": "t.keyword"
}
],
"sort": {
"s": "desc"
}
}
}
},
)
print(resp2) response = client.indices.create(
index: 'test',
body: {
mappings: {
properties: {
d: {
type: 'date'
}
}
}
}
)
puts response
response = client.bulk(
index: 'test',
refresh: true,
body: [
{
index: {}
},
{
s: 1,
m: 3.1415,
i: 1,
d: '2020-01-01T00:12:12Z',
t: 'cat'
},
{
index: {}
},
{
s: 2,
m: 1,
i: 6,
d: '2020-01-02T00:12:12Z',
t: 'dog'
},
{
index: {}
},
{
s: 3,
m: 2.71828,
i: -12,
d: '2019-12-31T00:12:12Z',
t: 'chicken'
}
]
)
puts response
response = client.search(
index: 'test',
filter_path: 'aggregations',
body: {
aggregations: {
tm: {
top_metrics: {
metrics: [
{
field: 'm'
},
{
field: 'i'
},
{
field: 'd'
},
{
field: 't.keyword'
}
],
sort: {
s: 'desc'
}
}
}
}
}
)
puts response const response = await client.indices.create({
index: "test",
mappings: {
properties: {
d: {
type: "date",
},
},
},
});
console.log(response);
const response1 = await client.bulk({
index: "test",
refresh: "true",
operations: [
{
index: {},
},
{
s: 1,
m: 3.1415,
i: 1,
d: "2020-01-01T00:12:12Z",
t: "cat",
},
{
index: {},
},
{
s: 2,
m: 1,
i: 6,
d: "2020-01-02T00:12:12Z",
t: "dog",
},
{
index: {},
},
{
s: 3,
m: 2.71828,
i: -12,
d: "2019-12-31T00:12:12Z",
t: "chicken",
},
],
});
console.log(response1);
const response2 = await client.search({
index: "test",
filter_path: "aggregations",
aggs: {
tm: {
top_metrics: {
metrics: [
{
field: "m",
},
{
field: "i",
},
{
field: "d",
},
{
field: "t.keyword",
},
],
sort: {
s: "desc",
},
},
},
},
});
console.log(response2); PUT /test
{
"mappings": {
"properties": {
"d": {"type": "date"}
}
}
}
POST /test/_bulk?refresh
{"index": {}}
{"s": 1, "m": 3.1415, "i": 1, "d": "2020-01-01T00:12:12Z", "t": "cat"}
{"index": {}}
{"s": 2, "m": 1.0, "i": 6, "d": "2020-01-02T00:12:12Z", "t": "dog"}
{"index": {}}
{"s": 3, "m": 2.71828, "i": -12, "d": "2019-12-31T00:12:12Z", "t": "chicken"}
POST /test/_search?filter_path=aggregations
{
"aggs": {
"tm": {
"top_metrics": {
"metrics": [
{"field": "m"},
{"field": "i"},
{"field": "d"},
{"field": "t.keyword"}
],
"sort": {"s": "desc"}
}
}
}
} Что возвращает:
{
"aggregations": {
"tm": {
"top": [ {
"sort": [3],
"metrics": {
"m": 2.718280076980591,
"i": -12,
"d": "2019-12-31T00:12:12.000Z",
"t.keyword": "chicken"
}
} ]
}
}
} missing
Параметр missing определяет, как обрабатываются документы с отсутствующим значением. По умолчанию, если отсутствует какой-либо из ключевых компонентов, весь документ игнорируется. Можно обрабатывать отсутствующие компоненты как имеющие значение, используя параметр missing.
resp = client.indices.create(
index="my-index",
mappings={
"properties": {
"nr": {
"type": "integer"
},
"state": {
"type": "keyword"
}
}
},
)
print(resp)
resp1 = client.bulk(
index="my-index",
refresh=True,
operations=[
{
"index": {}
},
{
"nr": 1,
"state": "started"
},
{
"index": {}
},
{
"nr": 2,
"state": "stopped"
},
{
"index": {}
},
{
"nr": 3,
"state": "N/A"
},
{
"index": {}
},
{
"nr": 4
}
],
)
print(resp1)
resp2 = client.search(
index="my-index",
filter_path="aggregations",
aggs={
"my_top_metrics": {
"top_metrics": {
"metrics": {
"field": "state",
"missing": "N/A"
},
"sort": {
"nr": "desc"
}
}
}
},
)
print(resp2) response = client.indices.create(
index: 'my-index',
body: {
mappings: {
properties: {
nr: {
type: 'integer'
},
state: {
type: 'keyword'
}
}
}
}
)
puts response
response = client.bulk(
index: 'my-index',
refresh: true,
body: [
{
index: {}
},
{
nr: 1,
state: 'started'
},
{
index: {}
},
{
nr: 2,
state: 'stopped'
},
{
index: {}
},
{
nr: 3,
state: 'N/A'
},
{
index: {}
},
{
nr: 4
}
]
)
puts response
response = client.search(
index: 'my-index',
filter_path: 'aggregations',
body: {
aggregations: {
my_top_metrics: {
top_metrics: {
metrics: {
field: 'state',
missing: 'N/A'
},
sort: {
nr: 'desc'
}
}
}
}
}
)
puts response const response = await client.indices.create({
index: "my-index",
mappings: {
properties: {
nr: {
type: "integer",
},
state: {
type: "keyword",
},
},
},
});
console.log(response);
const response1 = await client.bulk({
index: "my-index",
refresh: "true",
operations: [
{
index: {},
},
{
nr: 1,
state: "started",
},
{
index: {},
},
{
nr: 2,
state: "stopped",
},
{
index: {},
},
{
nr: 3,
state: "N/A",
},
{
index: {},
},
{
nr: 4,
},
],
});
console.log(response1);
const response2 = await client.search({
index: "my-index",
filter_path: "aggregations",
aggs: {
my_top_metrics: {
top_metrics: {
metrics: {
field: "state",
missing: "N/A",
},
sort: {
nr: "desc",
},
},
},
},
});
console.log(response2); PUT /my-index
{
"mappings": {
"properties": {
"nr": { "type": "integer" },
"state": { "type": "keyword" }
}
}
}
POST /my-index/_bulk?refresh
{"index": {}}
{"nr": 1, "state": "started"}
{"index": {}}
{"nr": 2, "state": "stopped"}
{"index": {}}
{"nr": 3, "state": "N/A"}
{"index": {}}
{"nr": 4}
POST /my-index/_search?filter_path=aggregations
{
"aggs": {
"my_top_metrics": {
"top_metrics": {
"metrics": {
"field": "state",
"missing": "N/A"},
"sort": {"nr": "desc"}
}
}
}
} | Если вы хотите использовать агрегацию на текстовом содержимом, это должно быть поле типа | |
| В этом документе отсутствует значение поля | |
| Параметр |
Запрос приводит к следующему ответу:
{
"aggregations": {
"my_top_metrics": {
"top": [
{
"sort": [
4
],
"metrics": {
"state": "N/A"
}
}
]
}
}
} size
top_metrics может вернуть верхние несколько документов с метриками, используя параметр size:
resp = client.bulk(
index="test",
refresh=True,
operations=[
{
"index": {}
},
{
"s": 1,
"m": 3.1415
},
{
"index": {}
},
{
"s": 2,
"m": 1
},
{
"index": {}
},
{
"s": 3,
"m": 2.71828
}
],
)
print(resp)
resp1 = client.search(
index="test",
filter_path="aggregations",
aggs={
"tm": {
"top_metrics": {
"metrics": {
"field": "m"
},
"sort": {
"s": "desc"
},
"size": 3
}
}
},
)
print(resp1) response = client.bulk(
index: 'test',
refresh: true,
body: [
{
index: {}
},
{
s: 1,
m: 3.1415
},
{
index: {}
},
{
s: 2,
m: 1
},
{
index: {}
},
{
s: 3,
m: 2.71828
}
]
)
puts response
response = client.search(
index: 'test',
filter_path: 'aggregations',
body: {
aggregations: {
tm: {
top_metrics: {
metrics: {
field: 'm'
},
sort: {
s: 'desc'
},
size: 3
}
}
}
}
)
puts response const response = await client.bulk({
index: "test",
refresh: "true",
operations: [
{
index: {},
},
{
s: 1,
m: 3.1415,
},
{
index: {},
},
{
s: 2,
m: 1,
},
{
index: {},
},
{
s: 3,
m: 2.71828,
},
],
});
console.log(response);
const response1 = await client.search({
index: "test",
filter_path: "aggregations",
aggs: {
tm: {
top_metrics: {
metrics: {
field: "m",
},
sort: {
s: "desc",
},
size: 3,
},
},
},
});
console.log(response1); POST /test/_bulk?refresh
{"index": {}}
{"s": 1, "m": 3.1415}
{"index": {}}
{"s": 2, "m": 1.0}
{"index": {}}
{"s": 3, "m": 2.71828}
POST /test/_search?filter_path=aggregations
{
"aggs": {
"tm": {
"top_metrics": {
"metrics": {"field": "m"},
"sort": {"s": "desc"},
"size": 3
}
}
}
} Что возвращает:
{
"aggregations": {
"tm": {
"top": [
{"sort": [3], "metrics": {"m": 2.718280076980591 } },
{"sort": [2], "metrics": {"m": 1.0 } },
{"sort": [1], "metrics": {"m": 3.1414999961853027 } }
]
}
}
} Значение по умолчанию для size равно 1. Максимальное значение по умолчанию равно 10, потому что рабочая память агрегации «плотная», то есть мы выделяем size слотов для каждой корзины. 10 является очень консервативным максимальным значением по умолчанию, и вы можете увеличить его, изменив настройку индекса top_metrics_max_size. Но знайте, что большие значения могут потребовать значительного объёма памяти, особенно если они находятся внутри агрегации, которая создаёт много корзин, например, большой агрегации terms. Если вам всё же нужно его увеличить, используйте что-то вроде:
resp = client.indices.put_settings(
index="test",
settings={
"top_metrics_max_size": 100
},
)
print(resp) response = client.indices.put_settings(
index: 'test',
body: {
top_metrics_max_size: 100
}
)
puts response const response = await client.indices.putSettings({
index: "test",
settings: {
top_metrics_max_size: 100,
},
});
console.log(response); PUT /test/_settings
{
"top_metrics_max_size": 100
} Если size больше, чем 1, агрегация top_metrics не может быть целевым объектом сортировки.
Примеры
Использование с агрегацией Terms
Эта агрегация может быть весьма полезна внутри агрегации terms, чтобы, например, найти последнее значение, сообщенное каждым сервером.
resp = client.indices.create(
index="node",
mappings={
"properties": {
"ip": {
"type": "ip"
},
"date": {
"type": "date"
}
}
},
)
print(resp)
resp1 = client.bulk(
index="node",
refresh=True,
operations=[
{
"index": {}
},
{
"ip": "192.168.0.1",
"date": "2020-01-01T01:01:01",
"m": 1
},
{
"index": {}
},
{
"ip": "192.168.0.1",
"date": "2020-01-01T02:01:01",
"m": 2
},
{
"index": {}
},
{
"ip": "192.168.0.2",
"date": "2020-01-01T02:01:01",
"m": 3
}
],
)
print(resp1)
resp2 = client.search(
index="node",
filter_path="aggregations",
aggs={
"ip": {
"terms": {
"field": "ip"
},
"aggs": {
"tm": {
"top_metrics": {
"metrics": {
"field": "m"
},
"sort": {
"date": "desc"
}
}
}
}
}
},
)
print(resp2) response = client.indices.create(
index: 'node',
body: {
mappings: {
properties: {
ip: {
type: 'ip'
},
date: {
type: 'date'
}
}
}
}
)
puts response
response = client.bulk(
index: 'node',
refresh: true,
body: [
{
index: {}
},
{
ip: '192.168.0.1',
date: '2020-01-01T01:01:01',
m: 1
},
{
index: {}
},
{
ip: '192.168.0.1',
date: '2020-01-01T02:01:01',
m: 2
},
{
index: {}
},
{
ip: '192.168.0.2',
date: '2020-01-01T02:01:01',
m: 3
}
]
)
puts response
response = client.search(
index: 'node',
filter_path: 'aggregations',
body: {
aggregations: {
ip: {
terms: {
field: 'ip'
},
aggregations: {
tm: {
top_metrics: {
metrics: {
field: 'm'
},
sort: {
date: 'desc'
}
}
}
}
}
}
}
)
puts response const response = await client.indices.create({
index: "node",
mappings: {
properties: {
ip: {
type: "ip",
},
date: {
type: "date",
},
},
},
});
console.log(response);
const response1 = await client.bulk({
index: "node",
refresh: "true",
operations: [
{
index: {},
},
{
ip: "192.168.0.1",
date: "2020-01-01T01:01:01",
m: 1,
},
{
index: {},
},
{
ip: "192.168.0.1",
date: "2020-01-01T02:01:01",
m: 2,
},
{
index: {},
},
{
ip: "192.168.0.2",
date: "2020-01-01T02:01:01",
m: 3,
},
],
});
console.log(response1);
const response2 = await client.search({
index: "node",
filter_path: "aggregations",
aggs: {
ip: {
terms: {
field: "ip",
},
aggs: {
tm: {
top_metrics: {
metrics: {
field: "m",
},
sort: {
date: "desc",
},
},
},
},
},
},
});
console.log(response2); PUT /node
{
"mappings": {
"properties": {
"ip": {"type": "ip"},
"date": {"type": "date"}
}
}
}
POST /node/_bulk?refresh
{"index": {}}
{"ip": "192.168.0.1", "date": "2020-01-01T01:01:01", "m": 1}
{"index": {}}
{"ip": "192.168.0.1", "date": "2020-01-01T02:01:01", "m": 2}
{"index": {}}
{"ip": "192.168.0.2", "date": "2020-01-01T02:01:01", "m": 3}
POST /node/_search?filter_path=aggregations
{
"aggs": {
"ip": {
"terms": {
"field": "ip"
},
"aggs": {
"tm": {
"top_metrics": {
"metrics": {"field": "m"},
"sort": {"date": "desc"}
}
}
}
}
}
} Что возвращает:
{
"aggregations": {
"ip": {
"buckets": [
{
"key": "192.168.0.1",
"doc_count": 2,
"tm": {
"top": [ {"sort": ["2020-01-01T02:01:01.000Z"], "metrics": {"m": 2 } } ]
}
},
{
"key": "192.168.0.2",
"doc_count": 1,
"tm": {
"top": [ {"sort": ["2020-01-01T02:01:01.000Z"], "metrics": {"m": 3 } } ]
}
}
],
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0
}
}
} В отличие от top_hits, вы можете сортировать корзины по результатам этого метрики:
resp = client.search(
index="node",
filter_path="aggregations",
aggs={
"ip": {
"terms": {
"field": "ip",
"order": {
"tm.m": "desc"
}
},
"aggs": {
"tm": {
"top_metrics": {
"metrics": {
"field": "m"
},
"sort": {
"date": "desc"
}
}
}
}
}
},
)
print(resp) response = client.search(
index: 'node',
filter_path: 'aggregations',
body: {
aggregations: {
ip: {
terms: {
field: 'ip',
order: {
'tm.m' => 'desc'
}
},
aggregations: {
tm: {
top_metrics: {
metrics: {
field: 'm'
},
sort: {
date: 'desc'
}
}
}
}
}
}
}
)
puts response const response = await client.search({
index: "node",
filter_path: "aggregations",
aggs: {
ip: {
terms: {
field: "ip",
order: {
"tm.m": "desc",
},
},
aggs: {
tm: {
top_metrics: {
metrics: {
field: "m",
},
sort: {
date: "desc",
},
},
},
},
},
},
});
console.log(response); POST /node/_search?filter_path=aggregations
{
"aggs": {
"ip": {
"terms": {
"field": "ip",
"order": {"tm.m": "desc"}
},
"aggs": {
"tm": {
"top_metrics": {
"metrics": {"field": "m"},
"sort": {"date": "desc"}
}
}
}
}
}
} Что возвращает:
{
"aggregations": {
"ip": {
"buckets": [
{
"key": "192.168.0.2",
"doc_count": 1,
"tm": {
"top": [ {"sort": ["2020-01-01T02:01:01.000Z"], "metrics": {"m": 3 } } ]
}
},
{
"key": "192.168.0.1",
"doc_count": 2,
"tm": {
"top": [ {"sort": ["2020-01-01T02:01:01.000Z"], "metrics": {"m": 2 } } ]
}
}
],
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0
}
}
} Смешанные типы сортировки
Сортировка top_metrics по полю, имеющему разные типы в разных индексах, приводит к несколько неожиданным результатам: поля с плавающей точкой всегда сортируются независимо от целых чисел.
resp = client.bulk(
index="test",
refresh=True,
operations=[
{
"index": {
"_index": "test1"
}
},
{
"s": 1,
"m": 3.1415
},
{
"index": {
"_index": "test1"
}
},
{
"s": 2,
"m": 1
},
{
"index": {
"_index": "test2"
}
},
{
"s": 3.1,
"m": 2.71828
}
],
)
print(resp)
resp1 = client.search(
index="test*",
filter_path="aggregations",
aggs={
"tm": {
"top_metrics": {
"metrics": {
"field": "m"
},
"sort": {
"s": "asc"
}
}
}
},
)
print(resp1) response = client.bulk(
index: 'test',
refresh: true,
body: [
{
index: {
_index: 'test1'
}
},
{
s: 1,
m: 3.1415
},
{
index: {
_index: 'test1'
}
},
{
s: 2,
m: 1
},
{
index: {
_index: 'test2'
}
},
{
s: 3.1,
m: 2.71828
}
]
)
puts response
response = client.search(
index: 'test*',
filter_path: 'aggregations',
body: {
aggregations: {
tm: {
top_metrics: {
metrics: {
field: 'm'
},
sort: {
s: 'asc'
}
}
}
}
}
)
puts response const response = await client.bulk({
index: "test",
refresh: "true",
operations: [
{
index: {
_index: "test1",
},
},
{
s: 1,
m: 3.1415,
},
{
index: {
_index: "test1",
},
},
{
s: 2,
m: 1,
},
{
index: {
_index: "test2",
},
},
{
s: 3.1,
m: 2.71828,
},
],
});
console.log(response);
const response1 = await client.search({
index: "test*",
filter_path: "aggregations",
aggs: {
tm: {
top_metrics: {
metrics: {
field: "m",
},
sort: {
s: "asc",
},
},
},
},
});
console.log(response1); POST /test/_bulk?refresh
{"index": {"_index": "test1"}}
{"s": 1, "m": 3.1415}
{"index": {"_index": "test1"}}
{"s": 2, "m": 1}
{"index": {"_index": "test2"}}
{"s": 3.1, "m": 2.71828}
POST /test*/_search?filter_path=aggregations
{
"aggs": {
"tm": {
"top_metrics": {
"metrics": {"field": "m"},
"sort": {"s": "asc"}
}
}
}
} Что возвращает:
{
"aggregations": {
"tm": {
"top": [ {"sort": [3.0999999046325684], "metrics": {"m": 2.718280076980591 } } ]
}
}
} Хотя это лучше, чем ошибка, это вероятно не то, чего вы ожидали. Хотя при этом теряется точность, вы можете явно преобразовать поля целых чисел в числа с плавающей точкой, например, так:
resp = client.search(
index="test*",
filter_path="aggregations",
aggs={
"tm": {
"top_metrics": {
"metrics": {
"field": "m"
},
"sort": {
"s": {
"order": "asc",
"numeric_type": "double"
}
}
}
}
},
)
print(resp) response = client.search(
index: 'test*',
filter_path: 'aggregations',
body: {
aggregations: {
tm: {
top_metrics: {
metrics: {
field: 'm'
},
sort: {
s: {
order: 'asc',
numeric_type: 'double'
}
}
}
}
}
}
)
puts response const response = await client.search({
index: "test*",
filter_path: "aggregations",
aggs: {
tm: {
top_metrics: {
metrics: {
field: "m",
},
sort: {
s: {
order: "asc",
numeric_type: "double",
},
},
},
},
},
});
console.log(response); POST /test*/_search?filter_path=aggregations
{
"aggs": {
"tm": {
"top_metrics": {
"metrics": {"field": "m"},
"sort": {"s": {"order": "asc", "numeric_type": "double"}}
}
}
}
} Что возвращает гораздо более ожидаемое:
{
"aggregations": {
"tm": {
"top": [ {"sort": [1.0], "metrics": {"m": 3.1414999961853027 } } ]
}
}
} Использование в агрегациях поэтапной обработки
top_metrics может использоваться в агрегациях поэтапной обработки, которые потребляют по одному значению на каждый контейнер, например, в bucket_selector, который выполняет фильтрацию по каждому контейнеру, аналогично использованию предложения HAVING в SQL. Это требует установки size в 1 и указания правильного пути для передачи (единственного) метрики в оболочку агрегатора. Например:
resp = client.search(
index="test*",
filter_path="aggregations",
aggs={
"ip": {
"terms": {
"field": "ip"
},
"aggs": {
"tm": {
"top_metrics": {
"metrics": {
"field": "m"
},
"sort": {
"s": "desc"
},
"size": 1
}
},
"having_tm": {
"bucket_selector": {
"buckets_path": {
"top_m": "tm[m]"
},
"script": "params.top_m < 1000"
}
}
}
}
},
)
print(resp) response = client.search(
index: 'test*',
filter_path: 'aggregations',
body: {
aggregations: {
ip: {
terms: {
field: 'ip'
},
aggregations: {
tm: {
top_metrics: {
metrics: {
field: 'm'
},
sort: {
s: 'desc'
},
size: 1
}
},
having_tm: {
bucket_selector: {
buckets_path: {
top_m: 'tm[m]'
},
script: 'params.top_m < 1000'
}
}
}
}
}
}
)
puts response const response = await client.search({
index: "test*",
filter_path: "aggregations",
aggs: {
ip: {
terms: {
field: "ip",
},
aggs: {
tm: {
top_metrics: {
metrics: {
field: "m",
},
sort: {
s: "desc",
},
size: 1,
},
},
having_tm: {
bucket_selector: {
buckets_path: {
top_m: "tm[m]",
},
script: "params.top_m < 1000",
},
},
},
},
},
});
console.log(response); POST /test*/_search?filter_path=aggregations
{
"aggs": {
"ip": {
"terms": {
"field": "ip"
},
"aggs": {
"tm": {
"top_metrics": {
"metrics": {"field": "m"},
"sort": {"s": "desc"},
"size": 1
}
},
"having_tm": {
"bucket_selector": {
"buckets_path": {
"top_m": "tm[m]"
},
"script": "params.top_m < 1000"
}
}
}
}
}
} Агрегатор bucket_path использует имя top_metrics tm и ключевое слово для метрики, предоставляющей значение агрегата, а именно m.
© 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-top-metrics.html