Reputation: 1
I have below logs in my opensearch DB along with many more.
{
"took": 2,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 5,
"relation": "eq"
},
"max_score": null,
"hits": [
{
"_index": "logs-test",
"_id": "NUWi8IYBR8llKo4TWxVe",
"_score": null,
"_source": {
"@timestamp": "2023-03-17T17:33:20.000000000Z",
"Body": {
"active_connections": "415",
"app_name": "app1",
"attack_event": "Attack started"
},
"Name": "app1-logs"
}
},
{
"_index": "logs-test",
"_id": "NUWi8IYBR8llKo4TWxVe",
"_score": null,
"_source": {
"@timestamp": "2023-03-17T17:33:30.000000000Z",
"Body": {
"active_connections": "415",
"app_name": "app1",
"attack_event": "Under Attack"
},
"Name": "app1-logs"
}
},
{
"_index": "logs-test",
"_id": "NUWi8IYBR8llKo4TWxVe",
"_score": null,
"_source": {
"@timestamp": "2023-03-17T17:33:40.000000000Z",
"Body": {
"active_connections": "415",
"app_name": "app1",
"attack_event": "Under Attack"
},
"Name": "app1-logs"
}
},
{
"_index": "logs-test",
"_id": "NUWi8IYBR8llKo4TWxVe",
"_score": null,
"_source": {
"@timestamp": "2023-03-17T17:33:50.000000000Z",
"Body": {
"active_connections": "415",
"app_name": "app1",
"attack_event": "Under Attack"
},
"Name": "app1-logs"
}
},
{
"_index": "logs-test",
"_id": "NUWi8IYBR8llKo4TWxVe",
"_score": null,
"_source": {
"@timestamp": "2023-03-17T17:34:10.000000000Z",
"Body": {
"active_connections": "415",
"app_name": "app1",
"attack_event": "Attack ended"
},
"Name": "app1-logs"
}
}
]
}
}
As we can see, I have multiple records with "attack_event" as "Under Attack". I'd just like to fetch only the latest record of it along with other events. I'm able to add the size response filtering on the whole query but not specifically on the "Under Attack" event.
Below is the hits array that I'd want to fetch in a single search request.
{
"hits": [
{
"_index": "logs-test",
"_id": "NUWi8IYBR8llKo4TWxVe",
"_score": null,
"_source": {
"@timestamp": "2023-03-17T17:33:20.000000000Z",
"Body": {
"active_connections": "415",
"app_name": "app1",
"attack_event": "Attack started"
},
"Name": "app1-logs"
}
},
{
"_index": "logs-test",
"_id": "NUWi8IYBR8llKo4TWxVe",
"_score": null,
"_source": {
"@timestamp": "2023-03-17T17:33:50.000000000Z",
"Body": {
"active_connections": "415",
"app_name": "app1",
"attack_event": "Under Attack"
},
"Name": "app1-logs"
}
},
{
"_index": "logs-test",
"_id": "NUWi8IYBR8llKo4TWxVe",
"_score": null,
"_source": {
"@timestamp": "2023-03-17T17:34:10.000000000Z",
"Body": {
"active_connections": "415",
"app_name": "app1",
"attack_event": "Attack ended"
},
"Name": "app1-logs"
}
}
]
}
Appreciate any help/hint with the necessary opensearch query.
curl -X GET http://<OPENSEARCH_HOST:PORT>/logs-test/_search?pretty -H "Content-Type: application/json" -d '{"query": {"bool": {"should": [{"match": {"Body.attack_event": "Attack started"}}, {"match": {"Body.attack_event": "Attack ended"}}, {"match": {"Body.attack_event": "Under Attack"}}]}}, "sort": [{"@timestamp": {"order": "asc"}}], "size": 2}'
This works but this filters the whole hits array to 2 records, but I'm not able to add the size(1) filtering on {"match": {"Body.attack_event": "Under Attack"}} which is what I really want.
Upvotes: 0
Views: 854
Reputation: 3680
I believe the following query is what you are looking for.
GET logs-test/_search
{
"size": 0,
"aggs": {
"all_active_connections": {
"terms": {
"field": "Body.active_connections",
"size": 1000
},
"aggs": {
"attack_started": {
"filter": {
"query": {
"term": {
"Body.attack_event": "Attack started"
}
}
},
"terms": {
"field": "Body.attack_event",
"size": 1,
"order": {
"@timestamp": "desc"
}
}
},
"under_attack": {
"filter": {
"query": {
"term": {
"Body.attack_event": "Under Attack"
}
}
},
"terms": {
"field": "Body.attack_event",
"size": 1,
"order": {
"@timestamp": "desc"
}
}
},
"attack_ended": {
"filter": {
"query": {
"term": {
"Body.attack_event": "Attack ended"
}
}
},
"terms": {
"field": "Body.attack_event",
"size": 1,
"order": {
"@timestamp": "desc"
}
}
}
}
}
}
}
Upvotes: 0