Вы можете получить желаемый результат не с помощью самого запроса, а с помощью комбинации агрегация терминов и вложенные агрегация лучших результатов.
Агрегация терминов отвечает за создание сегментов, в которых все элементы с одинаковым термином находятся в одном сегменте. Это то, что может генерировать ваши группы за transactionId
. Таким образом, агрегация лучших попаданий представляет собой агрегацию метрик, которую можно настроить для возврата x первых попаданий корзины в соответствии с заданным порядком сортировки. Это позволяет получить событие журнала с наибольшей временной меткой каждого сегмента.
Предполагая сопоставление ваших образцов данных по умолчанию (где строки индексируются как thekey (текст) и thekey.keyword (как неанализируемый текст)) этот запрос:
GET so-logs/_search
{
"size": 0,
"query": {
"bool": {
"must": [
{
"range": {
"eventTimestamp.keyword": {
"gte": 1500000000000,
"lte": 1507000000000
}
}
}
]
}
},
"aggs": {
"by_transaction_id": {
"terms": {
"field": "transactionId.keyword",
"size": 10
},
"aggs": {
"latest": {
"top_hits": {
"size": 1,
"sort": [
{
"eventTimestamp.keyword": {
"order": "desc"
}
}
]
}
}
}
}
}
}
выдаст следующий вывод:
{
"took": 7,
"timed_out": false,
"_shards": {
"total": 5,
"successful": 5,
"failed": 0
},
"hits": {
"total": 4,
"max_score": 0,
"hits": []
},
"aggregations": {
"by_transaction_id": {
"doc_count_error_upper_bound": 0,
"sum_other_doc_count": 0,
"buckets": [
{
"key": "id111",
"doc_count": 2,
"latest": {
"hits": {
"total": 2,
"max_score": null,
"hits": [
{
"_index": "so-logs",
"_type": "entry",
"_id": "AV6z9Yj4QYbhNp_FoXa1",
"_score": null,
"_source": {
"transactionId": "id111",
"eventTimestamp": "1505864112051",
"otherfieldA": "fieldAvalue",
"otherfieldB": "fieldBvalue"
},
"sort": [
"1505864112051"
]
}
]
}
}
},
{
"key": "id222",
"doc_count": 2,
"latest": {
"hits": {
"total": 2,
"max_score": null,
"hits": [
{
"_index": "so-logs",
"_type": "entry",
"_id": "AV6z9ZlOQYbhNp_FoXa4",
"_score": null,
"_source": {
"transactionId": "id222",
"eventTimestamp": "1505863719478",
"otherfieldA": "fieldAvalue",
"otherfieldB": "fieldBvalue"
},
"sort": [
"1505863719478"
]
}
]
}
}
}
]
}
}
}
где вы можете найти желаемые результаты внутри результатов агрегации by_transaction_id.latest
в соответствии с именами агрегации, определенными в запросе.
Имейте в виду, что агрегация терминов имеет ограничение на количество возвращаемых сегментов, и установка этого значения > 10 000, вероятно, не является разумной идеей с точки зрения производительности. Подробнее см. в разделе раздел о size
агрегации терминов. Если вы хотите иметь дело с огромным количеством различных идентификаторов транзакций, я бы предложил сделать избыточное хранилище «верхней» записи по идентификатору транзакции.
Кроме того, вам, вероятно, следует переключить поле eventTimestamp
на date
для повышения производительности и более широкий набор возможностей запроса.
person
Andreas Jägle
schedule
24.09.2017