Return distance in elasticsearch results?
Yes you can, by using a script field.
For instance, assuming your doc have a geo-point field called location
, you could use the following:
(note the \u0027
is just an escaped single quote, so \u0027location\u0027
is really 'location'
)
curl -XGET 'http://127.0.0.1:9200/geonames/_search?pretty=1' -d '{ "script_fields" : { "distance" : { "params" : { "lat" : 2.27, "lon" : 50.3 }, "script" : "doc[\u0027location\u0027].distanceInKm(lat,lon)" } }}'# [Thu Feb 16 11:20:29 2012] Response:# {# "hits" : {# "hits" : [# {# "_score" : 1,# "fields" : {# "distance" : 466.844095463887# },# "_index" : "geonames_1318324623",# "_id" : "6436641_en",# "_type" : "place"# },... etc
If you want the _source
field to be returned as well, then you can specify that as follows:
curl -XGET 'http://127.0.0.1:9200/geonames/_search?pretty=1' -d '{ "fields" : [ "_source" ], "script_fields" : { "distance" : { "params" : { "lat" : 2.27, "lon" : 50.3 }, "script" : "doc[\u0027location\u0027].distanceInKm(lat,lon)" } }}'
Great answer by DrTech ... here is an updated version for Elasticsearch 5.x with painless as the script language. I also added "store_fields" to include _source
in the result:
curl -XGET 'http://127.0.0.1:9200/geonames/_search?pretty=1' -d '{ "stored_fields" : [ "_source" ], "script_fields" : { "distance" : { "script" : { "inline": "doc['location'].arcDistance(params.lat,params.lon) * 0.001", "lang": "painless", "params": { "lat": 2.27, "lon": 50.3 } } } }}'
To return distance aswel as as all the default fields/source, you could also do this:
To avoid that it sorts by distance (primarily) you just sort by _score (or whatever you want the results sorted by) first.
{ "sort": [ "_score", { "_geo_distance": { "location": { "lat": 40.715, "lon": -73.998 }, "order": "asc", "unit": "km", "distance_type": "plane" } } ]}