Le 12/06/2013 dans DevBlog

Ordering an IDs Query by ids with ElasticSearch

I play a lot with ElasticSearch those days (and I love it ♥),
and I came accross a missing feature.

I wanted to be able to query a list of document by ids (using the Ids Query) and get the documents in the same order as my ids.

By default, all my documents where fetched with a score of 1, so the order is not respected at all. ElasticSearch allow to ajust this score with script, and thats what I want to show you today!

Using Custom Score Query Function Score Query, we can add a script to specify manualy the document order:

{
  "query": {
    "function_score": {
      "boost_mode": "replace",
      "query": {
        "ids": {
          "type": "pony",
          "values": [
            "1337",
            "1664",
            "8888",
            "1111"
          ]
        }
      },
      "script_score": {
        "script": "
          count = ids.size();
          id    = org.elasticsearch.index.mapper.Uid.idFromUid(doc['_uid'].value);
          for (i = 0; i < count; i++) {
            if (id == ids[i]) { return count - i; }
          }",
        "params": {
          "ids": [
            "1337",
            "1664",
            "8888",
            "1111"
          ]
        },
        "lang": "mvel"
      }
    }
  },
  "size": 20,
  "from": 0,
  "explain": true
}

We give the script the same list of ids provided to the Ids Query and the score is the total number of ids minus the position in the array. This way, we can use Facets and all the power of the ElasticSearch query on a set of documents, unlike the _mget method.

EDIT October 2013: Code example updated to ElasticSearch 0.90.4 thanks to darklow, and here is an official feature request.