Pono
Pono

Reputation: 11786

How to return exactly one document per match in bool

I have documents with a (simplified) structure like this:

{uuid: 1, timestamp: "2017-10-18T01:30:00.000Z", "key": "value"}
{uuid: 2, timestamp: "2017-10-18T01:30:00.000Z", "key": "value"}
{uuid: 1, timestamp: "2017-10-18T01:25:00.000Z", "key": "value"}
{uuid: 2, timestamp: "2017-10-18T01:25:00.000Z", "key": "value"}
{uuid: 1, timestamp: "2017-10-18T01:20:00.000Z", "key": "value"}
{uuid: 2, timestamp: "2017-10-18T01:20:00.000Z", "key": "value"}

Now I'm trying to get exactly one document per uuid match like so (with the latest timestamp):

query: {
    bool: {
        should: [{
            match: {
                uuid: 1
            }
        },
        {
            match: {
                uuid: 2
            }
        }]
    }
}

However, the above query returns multiple documents for both uuids. How do I modify my query to return two latest documents with uuid 1 and 2 like so:

{uuid: 1, timestamp: "2017-10-18T01:30:00.000Z", "key": "value"}
{uuid: 2, timestamp: "2017-10-18T01:30:00.000Z", "key": "value"}

Upvotes: 1

Views: 205

Answers (1)

Val
Val

Reputation: 217424

I suggest using a terms aggregation coupled with a top_hits sub-aggregation, like this:

{
  "query": {
    "bool": {
      "should": [
        {
          "term": {
            "uuid.keyword": 1
          }
        },
        {
          "term": {
            "uuid.keyword": 2
          }
        }
      ]
    }
  },
  "aggs": {
    "uuids": {
      "terms": {
        "field": "uuid.keyword"
      },
      "aggs": {
        "latest": {
          "top_hits": {
            "size": 1,
            "sort": {
              "timestamp": "desc"
            }
          }
        }
      }
    }
  }
}

Upvotes: 3

Related Questions