Search code examples
elasticsearch

Sort search results in Elasticsearch by a script field


I have this query in Elasticsearch. It works fine but doesn't sort the results by the distance to the search point.

GET /place_names/_search
{
   "query": {
    "bool" : {
        "must" : {
          "match_all" : {}
        },
    "filter" : {
      "geo_distance" : {
          "distance" : "10km",
          "location" : {
              "lat" : 64, 
              "lon" : -22
          }
        }
      }
    }
   },
    "script_fields" : {
      "id": {"script": "doc['id']"},
      "name": {"script": "doc['name']"},
      "type": {"script": "doc['type']"},
      "location": {"script": "doc['location']"},
      "dist_to_point" : {
          "script" : "doc['location'].arcDistance(64, -22)"
      }
    }
}

I would like to sort the results by "dist_to_point". Is that possible?


Solution

  • You can use the built-in _geo_distance sort:

    GET /place_names/_search
    {
      "sort": [
        {
          "_geo_distance": {
            "location": {
              "lat": 64,
              "lon": -22
            },
            "distance_type" : "arc",
            "order": "asc"
          }
        }
      ]
    }
    

    Or apply a _script sort -- the two are equivalent:

    GET places/_search
    {
      "sort": [
        {
          "_geo_distance": {
            "location": {
              "lat": 64,
              "lon": -22
            },
            "distance_type": "arc",
            "order": "asc"
          }
        },
        {
          "_script": {
            "script": "doc['location'].arcDistance(64, -22)",
            "type": "number",
            "order": "asc"
          }
        }
      ]
    }
    

    But you cannot sort by a scripted fields because they only exist within the search API which is separated from the sort API (=they don't know about each other).