Query top 5 from multiple indices

There are two options:

Downside of using field collapsing is that it won't work on the _index metadata fied. So you will need to add an additional field to your documents that indicate what index these docs are in, so you can collapse on that field.

For example, given these docs in three indexes a, b and c:

    POST _bulk
    { "index" : { "_index": "a", "_type": "doc", "_id" : "1"}}
    { "foo" : "bar a", "my_index": "a"}
    { "index" : { "_index": "a", "_type": "doc", "_id" : "2"}}
    { "foo" : "bar a", "my_index": "a"}
    { "index" : { "_index": "b", "_type": "doc", "_id" : "3"}}
    { "foo" : "bar b", "my_index": "b"}
    { "index" : { "_index": "b", "_type": "doc", "_id" : "4"}}
    { "foo" : "bar b", "my_index": "b"}
    { "index" : { "_index": "c", "_type": "doc", "_id" : "5"}}
    { "foo" : "bar c", "my_index": "c"}
    { "index" : { "_index": "c", "_type": "doc", "_id" : "6"}}
    { "foo" : "bar c", "my_index": "c"}

You could run a collapse on the my_index.keyword field:

    GET a,b,c/_search
    {
      "query": {
        "match": {
          "foo": "bar"
        }
      },
      "collapse": {
        "field": "my_index.keyword",
        "inner_hits": {
          "name": "my_top_5",
          "size": 5
        }
      }
    }

Probably easier (because it doesn't require that additional my_index field) is the top hits aggregation. Given the docs above, the following aggregation request gives you what you're looking for:

GET a,b,c/_search
{
  "query": {
    "match": {
      "foo": "bar"
    }
  },
  "size": 0,
  "aggs": {
    "indices": {
      "terms": {
        "field": "_index"
      },
      "aggs": {
        "my_top_hits": {
          "top_hits": {
            "size": 5
          }
        }
      }
    }
  }
}
1 Like