GET /attractions/restaurant/_search
{
"query": {
"filtered": {
"filter": {
"geo_bounding_box": {
"location": { (1)
"top_left": {
"lat": 40.8,
"lon": -74.0
},
"bottom_right": {
"lat": 40.7,
"lon": -73.0
}
}
}
}
}
}
}
Geo Bounding Box Filter
This is by far the most efficient geo-filter because its calculation is very
simple. You provide it with the top, bottom, left, and right
coordinates of a rectangle, and all it does is compare the longitude with the
left and right coordinates, and the latitude with the top and bottom
coordinates:
-
These coordinates can also be specified as
bottom_leftandtop_right.
Optimizing Bounding Boxes
The geo_bounding_box is the one geo-filter that doesn’t require all
geo-points to be loaded into memory. Because all it has to do is check
whether the lat and lon values fall within the specified ranges, it can
use the inverted index to do a glorified range filter.
To use this optimization, the geo_point field must be mapped to
index the lat and lon values separately:
PUT /attractions
{
"mappings": {
"restaurant": {
"properties": {
"name": {
"type": "string"
},
"location": {
"type": "geo_point",
"lat_lon": true (1)
}
}
}
}
}
-
The
location.latandlocation.lonfields will be indexed separately. These fields can be used for searching, but their values cannot be retrieved.
Now, when we run our query, we have to tell Elasticsearch to use the indexed
lat and lon values:
GET /attractions/restaurant/_search
{
"query": {
"filtered": {
"filter": {
"geo_bounding_box": {
"type": "indexed", (1)
"location": {
"top_left": {
"lat": 40.8,
"lon": -74.0
},
"bottom_right": {
"lat": 40.7,
"lon": -73.0
}
}
}
}
}
}
}
-
Setting the
typeparameter toindexed(instead of the defaultmemory) tells Elasticsearch to use the inverted index for this filter.
|
Caution
|
While a geo_point field can contain multiple geo-points, the
lat_lon optimization can be used only on fields that contain a single
geo-point.
|