Я внедряю решение для поиска событий на основе упругого поиска. Документы представляют события изменения состояния, связанные полем id
в источнике _. Поле sequence
начинается с 0
, так что самая высокая последовательность для id
является последним событием для id
. На практике дополнительные данные будут доступны только по первому событию, а последующие события будут содержать только те поля, которые изменились. Цель состояла в том, чтобы иметь индекс, к которому я никогда не должен отправлять обновления, только вставки.
Попытка создать запрос, который будет возвращать первое и последнее события, сгруппированные по их идентификатору, если только, если их последнее событие status
соответствует READY
.
Пример данных:
[
{
"_index":"events",
"_type":"event",
"_id":"AWcFf2N-IqNGd75vWMgc",
"_score":1,
"_source":{
"id":"event_chain-1",
"status":"SENT",
"sequence":1,
"timestamp":"1541985493824",
"export_batch_id":"103709fe-959f-4b4e-8255-ef59f18a3cf6"
}
},
{
"_index":"events",
"_type":"event",
"_id":"AWbQomwoIqNGd75vWMf6",
"_score":1,
"_source":{
"id":"event_chain-1",
"status":"READY",
"sequence":"0",
"timestamp":"2018-10-31T00:00:00Z"
}
},
{
"_index":"events",
"_type":"event",
"_id":"AWbQomwoIqNGd75vWabc",
"_score":1,
"_source":{
"id":"event_chain-2",
"status":"READY",
"sequence":"0",
"timestamp":"2018-10-31T00:00:00Z"
}
}
]
Я написал агрегацию терминов в поле id.keyword и две субагрегации top_hits, чтобы получить первое и последнее события, упорядочив последовательность и взяв верхний и нижний результаты соответственно.
Проблема заключается в том, что любое сопоставление, которое я выполняю с состоянием, происходит до агрегации, и мне нужен способ исключить из результатов агрегирования терминов любые попадания, в которых статус last_event не соответствует READY
.
Что у меня так далеко:
POST /events/_search
{
"size": 0,
"query": {
"bool": {
"must": {
"match": {
"status": "READY"
}
}
}
},
"aggs": {
"group_by_id": {
"terms": {
"field": "id.keyword",
"order": {
"_term": "asc"
},
"size": 100
},
"aggs": {
"latest_event": {
"top_hits": {
"sort": [
{
"sequence": {
"order": "desc"
}
}
],
"from": 0,
"size": 1
}
},
"first_event": {
"top_hits": {
"sort": [
{
"sequence": {
"order": "asc"
}
}
],
"from": 0,
"size": 1
}
}
}
},
"num_ready": {
"cardinality": {
"field": "id.keyword"
}
}
}
}
Это вернет два термина, один для event_chain-1
и один для event_chain-2
, когда мне нужен только один для event_chain-2
Термины agg size
, поэтому этот запрос можно запускать запланированными партиями, всегда очищая верхнюю часть результатов и обновляя цепочки, чтобы они не появлялись в следующем запросе.