When you are working with geo locations, one of the common tasks is to filter results based on its distance from a location. The geo_distance
filter is used to achieve this goal.
You need a working ElasticSearch cluster and the data populated with the geo populate script.
Searching documents in which pin.location
is 200km
distant from the lat
value 40
and the lon
value 70
, is done using a similar query as follows:
curl -XGET 'http://127.0.0.1:9200/test-mindex/_search -d '{ "query": { "filtered": { "filter": { "geo_distance": { "pin.location": { "lat": 40, "lon": 70 }, "distance": "200km", "optimize_bbox": "memory" } }, "query": { "match_all": {} } } } }'
As we discussed in the Mapping a GeoPoint field recipe there are several ways to define GeoPoint and it is internally saved in an optimized way to be searched.
The distance filter executes a distance calculation between a given GeoPoint and the points in documents, returning hits that verify the distance.
The parameters that control the distance filter are as follows:
pin.location
and (40
, 70
).distance
: This parameter defines the distance to be considered. It is usually expressed as a string by a number preceded by a unit.in
or inch
yd
or yards
m
or miles
km
or kilometers
m
or meters
mm
or millimeters
cm
or centimeters
distance_type
(default arc
) (valid choices are arc
/place
): This parameter defines the type of algorithm to calculate the distance.optimize_bbox
: This parameter defines how to filter first with a bounding box to improve performance. This kind of optimization removes a lot of document evaluations limiting the check to values that match a square. Valid values for this parameter are as follows:memory
(default): This value checks the memory.indexed
: This value checks using indexing values. It works only if lat
and lon
are indexed.none
: This value disables the bounding box optimization.There is also a range version of this filter that allows filter by range. The geo_distance_range
filter works as a standard range filter (refer to the Using range query/filter recipe) in which the range is defined in from
and to
parameters. For example the previously discussed code can be converted into a range without the from
part as follows:
curl -XGET 'http://127.0.0.1:9200/test-mindex/_search -d '{ "query": { "filtered": { "filter": { "geo_distance_range": { "pin.location": { "lat": 40, "lon": 70 }, "to": "200km", "optimize_bbox": "memory" } }, "query": { "match_all": {} } } } }'
18.191.127.253