| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367 | [[query-dsl-geo-bounding-box-query]]=== Geo-bounding box query++++<titleabbrev>Geo-bounding box</titleabbrev>++++A query allowing to filter hits based on a point location using abounding box. Assuming the following indexed document:[source,console]--------------------------------------------------PUT /my_locations{    "mappings": {        "properties": {            "pin": {                "properties": {                    "location": {                        "type": "geo_point"                    }                }            }        }    }}PUT /my_locations/_doc/1{    "pin" : {        "location" : {            "lat" : 40.12,            "lon" : -71.34        }    }}--------------------------------------------------// TESTSETUPThen the following simple query can be executed with a`geo_bounding_box` filter:[source,console]--------------------------------------------------GET my_locations/_search{    "query": {        "bool" : {            "must" : {                "match_all" : {}            },            "filter" : {                "geo_bounding_box" : {                    "pin.location" : {                        "top_left" : {                            "lat" : 40.73,                            "lon" : -74.1                        },                        "bottom_right" : {                            "lat" : 40.01,                            "lon" : -71.12                        }                    }                }            }        }    }}--------------------------------------------------[float]==== Query Options[cols="<,<",options="header",]|=======================================================================|Option |Description|`_name` |Optional name field to identify the filter|`validation_method` |Set to `IGNORE_MALFORMED` toaccept geo points with invalid latitude or longitude, set to`COERCE` to also try to infer correct latitude or longitude. (default is `STRICT`).|`type` |Set to one of `indexed` or `memory` to defines whether this filter willbe executed in memory or indexed. See <<geo-bbox-type,Type>> below for further detailsDefault is `memory`.|=======================================================================[float]==== Accepted FormatsIn much the same way the geo_point type can accept differentrepresentations of the geo point, the filter can accept it as well:[float]===== Lat Lon As Properties[source,console]--------------------------------------------------GET my_locations/_search{    "query": {        "bool" : {            "must" : {                "match_all" : {}            },            "filter" : {                "geo_bounding_box" : {                    "pin.location" : {                        "top_left" : {                            "lat" : 40.73,                            "lon" : -74.1                        },                        "bottom_right" : {                            "lat" : 40.01,                            "lon" : -71.12                        }                    }                }            }        }    }}--------------------------------------------------[float]===== Lat Lon As ArrayFormat in `[lon, lat]`, note, the order of lon/lat here in order toconform with http://geojson.org/[GeoJSON].[source,console]--------------------------------------------------GET my_locations/_search{    "query": {        "bool" : {            "must" : {                "match_all" : {}            },            "filter" : {                "geo_bounding_box" : {                    "pin.location" : {                        "top_left" : [-74.1, 40.73],                        "bottom_right" : [-71.12, 40.01]                    }                }            }        }    }}--------------------------------------------------[float]===== Lat Lon As StringFormat in `lat,lon`.[source,console]--------------------------------------------------GET my_locations/_search{    "query": {        "bool" : {            "must" : {                "match_all" : {}            },            "filter" : {                "geo_bounding_box" : {                    "pin.location" : {                        "top_left" : "40.73, -74.1",                        "bottom_right" : "40.01, -71.12"                    }                }            }    }}}--------------------------------------------------[float]===== Bounding Box as Well-Known Text (WKT)[source,console]--------------------------------------------------GET my_locations/_search{    "query": {        "bool" : {            "must" : {                "match_all" : {}            },            "filter" : {                "geo_bounding_box" : {                    "pin.location" : {                        "wkt" : "BBOX (-74.1, -71.12, 40.73, 40.01)"                    }                }            }        }    }}--------------------------------------------------[float]===== Geohash[source,console]--------------------------------------------------GET my_locations/_search{    "query": {        "bool" : {            "must" : {                "match_all" : {}            },            "filter" : {                "geo_bounding_box" : {                    "pin.location" : {                        "top_left" : "dr5r9ydj2y73",                        "bottom_right" : "drj7teegpus6"                    }                }            }        }    }}--------------------------------------------------When geohashes are used to specify the bounding the edges of thebounding box, the geohashes are treated as rectangles. The boundingbox is defined in such a way that its top left corresponds to the topleft corner of the geohash specified in the `top_left` parameter andits bottom right is defined as the bottom right of the geohashspecified in the `bottom_right` parameter.In order to specify a bounding box that would match entire area of ageohash the geohash can be specified in both `top_left` and`bottom_right` parameters:[source,console]--------------------------------------------------GET my_locations/_search{    "query": {        "geo_bounding_box" : {            "pin.location" : {                "top_left" : "dr",                "bottom_right" : "dr"            }        }    }}--------------------------------------------------In this example, the geohash `dr` will produce the bounding boxquery with the top left corner at `45.0,-78.75` and the bottom rightcorner at `39.375,-67.5`.[float]==== VerticesThe vertices of the bounding box can either be set by `top_left` and`bottom_right` or by `top_right` and `bottom_left` parameters. Moreover the names `topLeft`, `bottomRight`, `topRight` and `bottomLeft`are supported. Instead of setting the values pairwise, one can usethe simple names `top`, `left`, `bottom` and `right` to set thevalues separately.[source,console]--------------------------------------------------GET my_locations/_search{    "query": {        "bool" : {            "must" : {                "match_all" : {}            },            "filter" : {                "geo_bounding_box" : {                    "pin.location" : {                        "top" : 40.73,                        "left" : -74.1,                        "bottom" : 40.01,                        "right" : -71.12                    }                }            }        }    }}--------------------------------------------------[float]==== geo_point TypeThe filter *requires* the `geo_point` type to be set on the relevantfield.[float]==== Multi Location Per DocumentThe filter can work with multiple locations / points per document. Oncea single location / point matches the filter, the document will beincluded in the filter[float][[geo-bbox-type]]==== TypeThe type of the bounding box execution by default is set to `memory`,which means in memory checks if the doc falls within the bounding boxrange. In some cases, an `indexed` option will perform faster (but notethat the `geo_point` type must have lat and lon indexed in this case).Note, when using the indexed option, multi locations per document fieldare not supported. Here is an example:[source,console]--------------------------------------------------GET my_locations/_search{    "query": {        "bool" : {            "must" : {                "match_all" : {}            },            "filter" : {                "geo_bounding_box" : {                    "pin.location" : {                        "top_left" : {                            "lat" : 40.73,                            "lon" : -74.1                        },                        "bottom_right" : {                            "lat" : 40.10,                            "lon" : -71.12                        }                    },                    "type" : "indexed"                }            }        }    }}--------------------------------------------------[float]==== Ignore UnmappedWhen set to `true` the `ignore_unmapped` option will ignore an unmapped fieldand will not match any documents for this query. This can be useful whenquerying multiple indexes which might have different mappings. When set to`false` (the default value) the query will throw an exception if the fieldis not mapped.[float]==== Notes on PrecisionGeopoints have limited precision and are always rounded down during index time.During the query time, upper boundaries of the bounding boxes are rounded down,while lower boundaries are rounded up. As a result, the points along on thelower bounds (bottom and left edges of the bounding box) might not make it intothe bounding box due to the rounding error. At the same time points alongsidethe upper bounds (top and right edges) might be selected by the query even ifthey are located slightly outside the edge. The rounding error should be lessthan 4.20e-8 degrees on the latitude and less than 8.39e-8 degrees on thelongitude, which translates to less than 1cm error even at the equator.
 |