geo-bounding-box-query.asciidoc 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344
  1. [[query-dsl-geo-bounding-box-query]]
  2. === Geo Bounding Box Query
  3. A query allowing to filter hits based on a point location using a
  4. bounding box. Assuming the following indexed document:
  5. [source,js]
  6. --------------------------------------------------
  7. PUT /my_locations
  8. {
  9. "mappings": {
  10. "_doc": {
  11. "properties": {
  12. "pin": {
  13. "properties": {
  14. "location": {
  15. "type": "geo_point"
  16. }
  17. }
  18. }
  19. }
  20. }
  21. }
  22. }
  23. PUT /my_locations/_doc/1
  24. {
  25. "pin" : {
  26. "location" : {
  27. "lat" : 40.12,
  28. "lon" : -71.34
  29. }
  30. }
  31. }
  32. --------------------------------------------------
  33. // CONSOLE
  34. // TESTSETUP
  35. Then the following simple query can be executed with a
  36. `geo_bounding_box` filter:
  37. [source,js]
  38. --------------------------------------------------
  39. GET /_search
  40. {
  41. "query": {
  42. "bool" : {
  43. "must" : {
  44. "match_all" : {}
  45. },
  46. "filter" : {
  47. "geo_bounding_box" : {
  48. "pin.location" : {
  49. "top_left" : {
  50. "lat" : 40.73,
  51. "lon" : -74.1
  52. },
  53. "bottom_right" : {
  54. "lat" : 40.01,
  55. "lon" : -71.12
  56. }
  57. }
  58. }
  59. }
  60. }
  61. }
  62. }
  63. --------------------------------------------------
  64. // CONSOLE
  65. [float]
  66. ==== Query Options
  67. [cols="<,<",options="header",]
  68. |=======================================================================
  69. |Option |Description
  70. |`_name` |Optional name field to identify the filter
  71. |`validation_method` |Set to `IGNORE_MALFORMED` to
  72. accept geo points with invalid latitude or longitude, set to
  73. `COERCE` to also try to infer correct latitude or longitude. (default is `STRICT`).
  74. |`type` |Set to one of `indexed` or `memory` to defines whether this filter will
  75. be executed in memory or indexed. See <<geo-bbox-type,Type>> below for further details
  76. Default is `memory`.
  77. |=======================================================================
  78. [float]
  79. ==== Accepted Formats
  80. In much the same way the geo_point type can accept different
  81. representations of the geo point, the filter can accept it as well:
  82. [float]
  83. ===== Lat Lon As Properties
  84. [source,js]
  85. --------------------------------------------------
  86. GET /_search
  87. {
  88. "query": {
  89. "bool" : {
  90. "must" : {
  91. "match_all" : {}
  92. },
  93. "filter" : {
  94. "geo_bounding_box" : {
  95. "pin.location" : {
  96. "top_left" : {
  97. "lat" : 40.73,
  98. "lon" : -74.1
  99. },
  100. "bottom_right" : {
  101. "lat" : 40.01,
  102. "lon" : -71.12
  103. }
  104. }
  105. }
  106. }
  107. }
  108. }
  109. }
  110. --------------------------------------------------
  111. // CONSOLE
  112. [float]
  113. ===== Lat Lon As Array
  114. Format in `[lon, lat]`, note, the order of lon/lat here in order to
  115. conform with http://geojson.org/[GeoJSON].
  116. [source,js]
  117. --------------------------------------------------
  118. GET /_search
  119. {
  120. "query": {
  121. "bool" : {
  122. "must" : {
  123. "match_all" : {}
  124. },
  125. "filter" : {
  126. "geo_bounding_box" : {
  127. "pin.location" : {
  128. "top_left" : [-74.1, 40.73],
  129. "bottom_right" : [-71.12, 40.01]
  130. }
  131. }
  132. }
  133. }
  134. }
  135. }
  136. --------------------------------------------------
  137. // CONSOLE
  138. [float]
  139. ===== Lat Lon As String
  140. Format in `lat,lon`.
  141. [source,js]
  142. --------------------------------------------------
  143. GET /_search
  144. {
  145. "query": {
  146. "bool" : {
  147. "must" : {
  148. "match_all" : {}
  149. },
  150. "filter" : {
  151. "geo_bounding_box" : {
  152. "pin.location" : {
  153. "top_left" : "40.73, -74.1",
  154. "bottom_right" : "40.01, -71.12"
  155. }
  156. }
  157. }
  158. }
  159. }
  160. }
  161. --------------------------------------------------
  162. // CONSOLE
  163. [float]
  164. ===== Bounding Box as Well-Known Text (WKT)
  165. [source,js]
  166. --------------------------------------------------
  167. GET /_search
  168. {
  169. "query": {
  170. "bool" : {
  171. "must" : {
  172. "match_all" : {}
  173. },
  174. "filter" : {
  175. "geo_bounding_box" : {
  176. "pin.location" : {
  177. "wkt" : "BBOX (-74.1, -71.12, 40.73, 40.01)"
  178. }
  179. }
  180. }
  181. }
  182. }
  183. }
  184. --------------------------------------------------
  185. // CONSOLE
  186. [float]
  187. ===== Geohash
  188. [source,js]
  189. --------------------------------------------------
  190. GET /_search
  191. {
  192. "query": {
  193. "bool" : {
  194. "must" : {
  195. "match_all" : {}
  196. },
  197. "filter" : {
  198. "geo_bounding_box" : {
  199. "pin.location" : {
  200. "top_left" : "dr5r9ydj2y73",
  201. "bottom_right" : "drj7teegpus6"
  202. }
  203. }
  204. }
  205. }
  206. }
  207. }
  208. --------------------------------------------------
  209. // CONSOLE
  210. [float]
  211. ==== Vertices
  212. The vertices of the bounding box can either be set by `top_left` and
  213. `bottom_right` or by `top_right` and `bottom_left` parameters. More
  214. over the names `topLeft`, `bottomRight`, `topRight` and `bottomLeft`
  215. are supported. Instead of setting the values pairwise, one can use
  216. the simple names `top`, `left`, `bottom` and `right` to set the
  217. values separately.
  218. [source,js]
  219. --------------------------------------------------
  220. GET /_search
  221. {
  222. "query": {
  223. "bool" : {
  224. "must" : {
  225. "match_all" : {}
  226. },
  227. "filter" : {
  228. "geo_bounding_box" : {
  229. "pin.location" : {
  230. "top" : 40.73,
  231. "left" : -74.1,
  232. "bottom" : 40.01,
  233. "right" : -71.12
  234. }
  235. }
  236. }
  237. }
  238. }
  239. }
  240. --------------------------------------------------
  241. // CONSOLE
  242. [float]
  243. ==== geo_point Type
  244. The filter *requires* the `geo_point` type to be set on the relevant
  245. field.
  246. [float]
  247. ==== Multi Location Per Document
  248. The filter can work with multiple locations / points per document. Once
  249. a single location / point matches the filter, the document will be
  250. included in the filter
  251. [float]
  252. [[geo-bbox-type]]
  253. ==== Type
  254. The type of the bounding box execution by default is set to `memory`,
  255. which means in memory checks if the doc falls within the bounding box
  256. range. In some cases, an `indexed` option will perform faster (but note
  257. that the `geo_point` type must have lat and lon indexed in this case).
  258. Note, when using the indexed option, multi locations per document field
  259. are not supported. Here is an example:
  260. [source,js]
  261. --------------------------------------------------
  262. GET /_search
  263. {
  264. "query": {
  265. "bool" : {
  266. "must" : {
  267. "match_all" : {}
  268. },
  269. "filter" : {
  270. "geo_bounding_box" : {
  271. "pin.location" : {
  272. "top_left" : {
  273. "lat" : 40.73,
  274. "lon" : -74.1
  275. },
  276. "bottom_right" : {
  277. "lat" : 40.10,
  278. "lon" : -71.12
  279. }
  280. },
  281. "type" : "indexed"
  282. }
  283. }
  284. }
  285. }
  286. }
  287. --------------------------------------------------
  288. // CONSOLE
  289. [float]
  290. ==== Ignore Unmapped
  291. When set to `true` the `ignore_unmapped` option will ignore an unmapped field
  292. and will not match any documents for this query. This can be useful when
  293. querying multiple indexes which might have different mappings. When set to
  294. `false` (the default value) the query will throw an exception if the field
  295. is not mapped.
  296. [float]
  297. ==== Notes on Precision
  298. Geopoints have limited precision and are always rounded down during index time.
  299. During the query time, upper boundaries of the bounding boxes are rounded down,
  300. while lower boundaries are rounded up. As a result, the points along on the
  301. lower bounds (bottom and left edges of the bounding box) might not make it into
  302. the bounding box due to the rounding error. At the same time points alongside
  303. the upper bounds (top and right edges) might be selected by the query even if
  304. they are located slightly outside the edge. The rounding error should be less
  305. than 4.20e-8 degrees on the latitude and less than 8.39e-8 degrees on the
  306. longitude, which translates to less than 1cm error even at the equator.