#elasticsearch
#elasticsearch
Вопрос:
Новичок в Elasticsearch здесь. У меня есть серия сообщений журнала, подобных этим
{
"@timestamp": "whatever",
"type": "toBeMonitored",
"success": true
}
Мне было поручено отреагировать на изменение -30% от общего количества успешных сообщений по сравнению со вчерашним тем же интервалом. Итак, если я выполню проверку сегодня в 8 утра, я должен сравнить сегодняшнее общее количество с полуночи до 8 утра со вчерашним тем же интервалом.
Я попытался создать агрегацию гистограммы даты, но я хотел бы иметь процент разницы в качестве результата запроса и не выполнять математику на стороне разработки.
{
"size": 0,
"query": {
"bool": {
"filter": [
{
"term": {
"type": "toBeMonitored"
}
},
{
"term": {
"status": true
}
},
{
"range": {
"@timestamp": {
"gte": "now-1d/d",
"lte": "now/h"
}
}
}
]
}
},
"aggs": {
"histo": {
"date_histogram": {
"field": "@timestamp",
"fixed_interval": "1h"
}
}
}
}
Есть идеи о том, как это можно сделать?
Комментарии:
1. Лучше сделать это на стороне приложения.
Ответ №1:
Вы можете использовать derivative
агрегацию конвейера для достижения именно того, чего вы ожидаете:
POST /sales/_search
{
"size": 0,
"query": {
"bool": {
"filter": [
{
"term": {
"type": "toBeMonitored"
}
},
{
"term": {
"status": true
}
},
{
"range": {
"@timestamp": {
"gte": "now-1d/d",
"lte": "now/h"
}
}
}
]
}
},
"aggs": {
"histo": {
"date_histogram": {
"field": "@timestamp",
"fixed_interval": "1h"
},
"aggs": {
"successDiff": {
"derivative": {
"buckets_path": "_count"
}
}
}
}
}
}
В каждом сегменте вы получите разницу между количеством документов в предыдущем сегменте и текущим сегментом.
Комментарии:
1. Спасибо за ввод, я также смотрел на агрегацию производных. К сожалению, на самом деле это не так, поскольку мне все еще приходится перебирать все результаты на стороне приложения.
2. Я не уверен, что вы имеете в виду? Если вы укажете правильный размер интервала, у вас будут только два интересующих вас сегмента, а во втором у вас будет разница, которую вы ищете
3. Смотрите мой собственный ответ ниже
Ответ №2:
В итоге я отбросил date_histogram
агрегацию и использовал date_range
один. С ним намного проще работать, даже если он не возвращает разницу по сравнению со вчерашним аналогичным периодом времени. Я сделал это в коде.
{
"size": 0,
"query": {
"bool": {
"filter": [
{
"term": {
"type": "toBeMonitored"
}
},
{
"term": {
"status": true
}
},
{
"range": {
"@timestamp": {
"gte": "now-1d/d",
"lte": "now/h"
}
}
}
]
}
},
"aggs": {
"ranged_documents": {
"date_range": {
"field": "@timestamp",
"ranges": [
{
"key": "yesterday",
"from": "now-1d/d",
"to": "now-24h/h"
},
{
"key": "today",
"from": "now/d",
"to": "now/h"
}
],
"keyed": true
}
}
}
}
Этот запрос даст результат, аналогичный приведенному ниже
{
"_shards": {
"total": 42,
"failed": 0,
"successful": 42,
"skipped": 0
},
"hits": {
"hits": [],
"total": {
"value": 10000,
"relation": "gte"
},
"max_score": null
},
"took": 134,
"timed_out": false,
"aggregations": {
"ranged_documents": {
"buckets": {
"yesterday": {
"from_as_string": "2020-10-12T00:00:00.000Z",
"doc_count": 268300,
"to_as_string": "2020-10-12T12:00:00.000Z",
"from": 1602460800000,
"to": 1602504000000
},
"today": {
"from_as_string": "2020-10-13T00:00:00.000Z",
"doc_count": 251768,
"to_as_string": "2020-10-13T12:00:00.000Z",
"from": 1602547200000,
"to": 1602590400000
}
}
}
}
}