Question

I am using geodistance query in python like this

{
  "query": {
    "filtered": {
      "query": {
        "match_all": {}
      },
      "filter": {
        "geo_distance": {
          "distance": "20miles",
          "location": {
            "lat": 51.512497,
            "lon": -0.052098
          }
        }
      }
    }
  }
} 

It is working correctly. My problem is how to give "distance" a value from within the document. I have a field like this distance: 50 in my index for each record and I want to use it as a value of distance in geodistance. I tried "distance":doc['distance'].value but it is not working.

Was it helpful?

Solution

The ordinary queries and filters are not expecting scripts to be placed within them.

Assuming that you have stored a geo_point with the field name of location, then you want to use a script filter using the doc['field_name'].distanceInMiles(lat, lon) (as opposed to distance(lat, lon) because the standard units are meters as-of v1.0.0):

{
  "filtered" : {
    "query" : { "match_all" : { } },
    "filter" : {
      "script" : {
        "script" :
          "doc['location'].distanceInMiles(lat, lon) < doc['distance'].value",
        "params" : {
          "lat" : 51.512497,
          "lon" : -0.052098
        }
      }
    }
  }
}

If you are running an instance of Elasticsearch where it is using the previously standard units of miles (pre-v1.0.0), then you can use the plain distance function (or if your units for distance already happened to be in the now-standard meters as-of v1.0.0):

{
  "filtered" : {
    "query" : { "match_all" : { } },
    "filter" : {
      "script" : {
        "script" :
          "doc['location'].distance(lat, lon) < doc['distance'].value",
        "params" : {
          "lat" : 51.512497,
          "lon" : -0.052098
        }
      }
    }
  }
}

Note: you could supply the values of lat and lon directly within the script for one-off execution, but scripts are compiled and cached, so using parameters allows reuse and therefore faster execution after the first use.

As noted in the documentation, you can cache the result of the filter by adding "_cache" : true to the filter, but the result of the filter is not cached by default.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top