Reputation: 111
I am facing an issue with Elasticsearch. I would like use the geo distance feature to fetch all the item located N km maximum from a given localization.
Here is my DB schema:
{
"user_id": "abcde",
"pin" : {
"location" : {
"lat" : 40.12,
"lon" : -71.34
}
},
"is_active": true,
"action_zone": 50
}
I have this query which works pretty well:
{
"query": {
"bool" : {
"must" :
[{
"term": {
"is_active": True
}
}],
"filter" : {
"geo_distance" : {
"distance" : "200km",
"pin.location" : {
"lat" : 40,
"lon" : -70
}
}
}
}
}
}
Now, I would like to modify this query a bit to replace dynamically the distance (200km in my example) by the value "action_zone" of each item of in the DB.
That would be great if someone could help me. :)
Upvotes: 1
Views: 2261
Reputation: 111
I found the solution using a script :D Thanks anyway !
{
"query": {
"bool" : {
"must" :
[{
"term": {
"is_active": True
}
},{
"script" : {
"script" : {
"params": {
"lat": 40.8,
"lon": -70.1
},
"source": "doc['location'].arcDistance(params.lat, params.lon) / 1000 < doc['action_zone'].value",
"lang": "painless"
}
}
}]
}
}
}
}
Doc: https://www.elastic.co/guide/en/elasticsearch/reference/6.1/query-dsl-script-query.html
Upvotes: 4
Reputation: 217274
Unfortunately, the geo_distance
query doesn't allow to use scripting in order to specify a dynamic distance. What you could do, however, would be to use a terms
aggregation on the action_zone
field so as to bucket all your documents within a specific action zone.
{
"query": {
"bool": {
"must": [
{
"term": {
"is_active": True
}
}
],
"filter": {
"geo_distance": {
"distance": "200km",
"pin.location": {
"lat": 40,
"lon": -70
}
}
}
}
},
"aggs": {
"zones": {
"terms": {
"field": "action_zone"
}
}
}
}
Otherwise, you could also use a range
aggregation on the action_zone
field with a few specific distances:
{
"query": {
"bool": {
"must": [
{
"term": {
"is_active": "True"
}
}
],
"filter": {
"geo_distance": {
"distance": "200km",
"pin.location": {
"lat": 40,
"lon": -70
}
}
}
}
},
"aggs": {
"zones": {
"range": {
"field": "action_zone",
"ranges": [
{
"to": 50
},
{
"from": 50,
"to": 100
},
{
"from": 100,
"to": 150
},
{
"from": 150
}
]
}
}
}
}
Upvotes: 1