Как создать запрос, который может рассчитать разницу во времени?
У меня есть и индекс со следующими документами:
{name: 'Device1', type: 'start', 'eventTime': '2013-02-19 12:00:00'}
{name: 'Device2', type: 'start', 'eventTime': '2013-02-19 12:02:00'}
{name: 'Device1', type: 'stop', 'eventTime': '2013-02-19 12:45:00'}
{name: 'Device2', type: 'stop', 'eventTime': '2013-02-19 12:50:00'}
Я хотел бы создать запрос, который вернет мне новое поле с разницами во времени между eventTime, ограненными именем устройства и отношениями с типом поля. Для примера это должно быть:
{name: 'Device1', 'type': 'it really doesnt matter', eventTime: 'also doesnt matter', duration: '00:45:00'}
{name 'Device2', 'type': 'it really doesnt matter', eventTime: 'also doesnt matter', duration: '00:48:00'}
Возможно ли это с помощью языка поиска с эластичным поиском?
Ответы
Ответ 1
Я не считаю, что это возможно с тем, как у вас есть каждый документ в настоящее время. Если вы храните документы как:
{name: 'Device1', startTime: '2013-02-19 12:00:00', endTime: '2013-02-19 12:45:00'}
{name: 'Device2', startTime: '2013-02-19 12:02:00', endTime: '2013-02-19 12:50:00'}
Затем вы можете вернуть поле script, которое представляет собой разницу во времени.
{
"query" : {
...
},
"script_fields" : {
"timedifference" : {
"script" : "doc['endTime'].value - doc['startTime'].value"
}
}
}
Ответ 2
Вы можете посмотреть elapsed фильтр статистов.
В вашем случае использования вам нужно пометить начальный документ с помощью start_tag и остановить документ с помощью end_tag. Вы можете использовать "имя" как уникальное поле id.
Надеюсь, что это поможет!
Ответ 3
Ищет то же самое, здесь Я нашел хороший пример, чтобы ответить на этот вопрос, используя прошедшие фильтры, как сказал Ана, и объединив его с агрегатным фильтром.
Идея состоит в том, чтобы измерить время каждого этапа, а затем агрегировать информацию о времени между событиями в новое событие.
Итак, следуя примеру, указанному в ссылке, если у вас есть эти журналы:
2016-05-19T02:55:29.003 00e02f2f-32d5-9509-870a-f80e54dc8775 system1Enter
2016-05-19T02:55:29.200 00e02f2f-32d5-9509-870a-f80e54dc8775 system1Exit
2016-05-19T02:55:29.205 00e02f2f-32d5-9509-870a-f80e54dc8775 system2Enter
2016-05-19T02:55:29.453 00e02f2f-32d5-9509-870a-f80e54dc8775 system2Exit
Мы определяем три прошедших фильтра (по одному для каждого этапа в 1, 1- > 2 и в 2), а затем три совокупных фильтра, чтобы суммировать всю информацию о времени.
filter {
grok {
match => ["message", "%{TIMESTAMP_ISO8601:timestamp} %{UUID:messageId} %{WORD:event}"]
add_tag => [ "%{event}" ]
}
date {
match => [ "timestamp", "ISO8601"]
}
# Measures the execution time of system1
elapsed {
unique_id_field => "messageId"
start_tag => "system1Enter"
end_tag => "system1Exit"
new_event_on_match => true
add_tag => ["in1"]
}
# Measures the execution time of system2
elapsed {
unique_id_field => "messageId"
start_tag => "system2Enter"
end_tag => "system2Exit"
new_event_on_match => true
add_tag => ["in2"]
}
# Measures the time between system1 and system2
elapsed {
unique_id_field => "messageId"
start_tag => "system1Exit"
end_tag => "system2Enter"
new_event_on_match => true
add_tag => ["1->2"]
}
# Records the execution time of system1
if "in1" in [tags] and "elapsed" in [tags] {
aggregate {
task_id => "%{messageId}"
code => "map['report'] = [(event['elapsed_time']*1000).to_i]"
map_action => "create"
}
}
# Records the time between system1 and system2
if "1->2" in [tags] and "elapsed" in [tags] {
aggregate {
task_id => "%{messageId}"
code => "map['report'] << (event['elapsed_time']*1000).to_i"
map_action => "update"
}
}
# Records the execution time of system2
if "in2" in [tags] and "elapsed" in [tags] {
aggregate {
task_id => "%{messageId}"
code => "map['report'] << (event['elapsed_time']*1000).to_i; event['report'] = map['report'].join(':')"
map_action => "update"
end_of_task => true
}
}
}
После первых двух событий вы получите новое событие, которое показывает, что 197ms были потрачены в system1:
{
"@timestamp" => "2016-05-21T04:20:51.731Z",
"tags" => [ "elapsed", "elapsed_match", "in1" ],
"elapsed_time" => 0.197,
"messageId" => "00e02f2f-32d5-9509-870a-f80e54dc8775",
"elapsed_timestamp_start" => "2016-05-19T00:55:29.003Z"
}
И снова все кредиты отправляются автору исходного ответа:)
Ответ 4
Вы можете использовать scripted_metric для получения продолжительности.
{
"size": 0,
"aggs": {
"d_ids": {
"terms": {
"field": "name.keyword",
"size": 10
},
"aggs": {
"duration": {
"scripted_metric": {
"map_script": "if (doc.type.value == \"stop\") { params._agg.end = doc.eventTime.value; } else { params._agg.start = doc.eventTime.value; }",
"reduce_script": "long start = 0; long end = 0; for(h in params._aggs) { if(h.start != null) { start = h.start; } if (h.end != null) { end = h.end; } } return (end - start);"
}
}
}
}
}
}
Вот ответ от вышеуказанного запроса:
{
"took": 1,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"failed": 0
},
"hits": {
"total": 4,
"max_score": 0,
"hits": []
},
"aggregations": {
"d_ids": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
{
"key": "Device1",
"doc_count": 2,
"duration": {
"value": 2700000
}
},
{
"key": "Device2",
"doc_count": 2,
"duration": {
"value": 2880000
}
}
]
}
}
}
Длительность в миллисекундах