Reputation: 38899
I have a usecase where I have 2 types of locations (i.e. with geo_point type):
Now, when a query comes in with: lat/lon and radius=20, I expect this to happen:
This is what I have come up with using script:
{
"query": {
"match_all": {}
},
"filter": {
"script": {
"script": "!doc['geopoint'].empty && doc['coverage_type'].value == 'outgoing' ? doc['geopoint'].distanceInMiles(37,-121) <= doc['radius'].value : doc['geopoint'].distanceInMiles(37,-121) <= 20"
}
}
}
Where "37,-121" is input lat/lon and 20 is the input radius.
What do you think about the query, is this the best way to do it?
Originally posted this on ES mailing list, no luck.
Upvotes: 1
Views: 918
Reputation: 4216
That seems ok to me. An other way which is a bit more verbose would be to explode your script into various ES filters so that ES can optimize your request as much as possible (you would be able to use the specific geo_distance filter for one of your cases). For instance you could have something like this: (sorry if the json isn't exact, i do not have means to test it right now)
{
"query": {
"match_all": {}
},
"filter": {
"bool": {
"should": [
{
"and": [
{
"term": {
"coverage_type": "outgoing"
}
},
{
"script": {
"script": "!doc['geopoint'].empty && doc['geopoint'].distanceInMiles(37,-121) <= doc['radius'].value"
}
}
]
},
{
"and": [
{
"term": {
"coverage_type": "incoming"
}
},
{
"geo_distance" : {
"geopoint" : [ 37, -121 ],
"distance" : "20km"
}
}
]
}
]
}
}
}
You may have to add some specific filters to manage the fact a geopoint can be missing in your document and how you want to treat this. For instance, you may want to allow one to fetch all the documents without a geopoint in which case you could add a "missing" filter to the "should". I hope that helps.
Upvotes: 2