search-vector-tile-api.asciidoc 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755
  1. [[search-vector-tile-api]]
  2. === Search vector tile API
  3. ++++
  4. <titleabbrev>Search vector tile</titleabbrev>
  5. ++++
  6. experimental::[]
  7. Searches a vector tile for geospatial values. Returns results as a binary
  8. https://docs.mapbox.com/vector-tiles/specification[Mapbox vector tile].
  9. ////
  10. [source,console]
  11. ----
  12. PUT my-index
  13. {
  14. "mappings": {
  15. "properties": {
  16. "my-geo-field": {
  17. "type": "geo_point"
  18. }
  19. }
  20. }
  21. }
  22. PUT my-index/_doc/0?refresh
  23. {
  24. "my-geo-field": "37.3864953,-122.0863176"
  25. }
  26. ----
  27. ////
  28. [source,console]
  29. ----
  30. GET my-index/_mvt/my-geo-field/15/5271/12710
  31. ----
  32. // TEST[continued]
  33. [[search-vector-tile-api-request]]
  34. ==== {api-request-title}
  35. `GET <target>/_mvt/<field>/<zoom>/<x>/<y>`
  36. `POST <target>/_mvt/<field>/<zoom>/<x>/<y>`
  37. [[search-vector-tile-api-prereqs]]
  38. ==== {api-prereq-title}
  39. * Before using this API, you should be familiar with the
  40. https://github.com/mapbox/vector-tile-spec[Mapbox vector tile specification].
  41. * If the {es} {security-features} are enabled, you must have the `read`
  42. <<privileges-list-indices,index privilege>> for the target data stream, index,
  43. or alias.
  44. [[search-vector-tile-api-path-params]]
  45. ==== {api-path-parms-title}
  46. `<target>`::
  47. (Required, string) Comma-separated list of data streams, indices, or aliases to
  48. search. Supports wildcards (`*`). To search all data streams and indices, omit
  49. this parameter or use `*` or `_all`.
  50. `<field>`::
  51. (Required, string) Field containing geospatial values to return. Must be a
  52. <<geo-point,`geo_point`>> or <<geo-shape,`geo_shape`>> field. The field must
  53. have <<doc-values,doc values>> enabled. Cannot be a nested field.
  54. +
  55. NOTE: Vector tiles do not natively support geometry collections. For
  56. `geometrycollection` values in a `geo_shape` field, the API returns a `hits`
  57. layer feature for each element of the collection. This behavior may change may
  58. change in a future release.
  59. `<zoom>`::
  60. (Required, integer) Zoom level for the vector tile to search. Accepts `0`-`29`.
  61. `<x>`::
  62. (Required, integer) X coordinate for the vector tile to search.
  63. `<y>`::
  64. (Required, integer) Y coordinate for the vector tile to search.
  65. [[search-vector-tile-api-desc]]
  66. ==== {api-description-title}
  67. Internally, {es} translates a search vector tile API request into a
  68. <<search-search,search>> containing:
  69. * A <<query-dsl-geo-bounding-box-query,`geo_bounding_box`>> query on the
  70. `<field>`. The query uses the `<zoom>/<x>/<y>` tile as a bounding box.
  71. * A <<search-aggregations-bucket-geotilegrid-aggregation,`geotile_grid`>>
  72. aggregation on the `<field>`. The aggregation uses the `<zoom>/<x>/<y>` tile as
  73. a bounding box.
  74. * Optionally, a
  75. <<search-aggregations-metrics-geobounds-aggregation,`geo_bounds`>> aggregation
  76. on the `<field>`. The search only includes this aggregation if the
  77. `exact_bounds` parameter is `true`.
  78. For example, {es} may translate a search vector tile API request with an
  79. `exact_bounds` argument of `true` into the following search:
  80. [source,console]
  81. ----
  82. GET my-index/_search
  83. {
  84. "size": 10000,
  85. "query": {
  86. "geo_bounding_box": {
  87. "my-geo-field": {
  88. "top_left": {
  89. "lat": -40.979898069620134,
  90. "lon": -45
  91. },
  92. "bottom_right": {
  93. "lat": -66.51326044311186,
  94. "lon": 0
  95. }
  96. }
  97. }
  98. },
  99. "aggregations": {
  100. "grid": {
  101. "geotile_grid": {
  102. "field": "my-geo-field",
  103. "precision": 11,
  104. "size": 65536,
  105. "bounds": {
  106. "top_left": {
  107. "lat": -40.979898069620134,
  108. "lon": -45
  109. },
  110. "bottom_right": {
  111. "lat": -66.51326044311186,
  112. "lon": 0
  113. }
  114. }
  115. }
  116. },
  117. "bounds": {
  118. "geo_bounds": {
  119. "field": "my-geo-field",
  120. "wrap_longitude": false
  121. }
  122. }
  123. }
  124. }
  125. ----
  126. // TEST[continued]
  127. The API returns results as a binary
  128. https://github.com/mapbox/vector-tile-spec[Mapbox vector tile]. Mapbox vector
  129. tiles are encoded as https://github.com/protocolbuffers/protobuf[Google
  130. Protobufs (PBF)]. By default, the tile contains three layers:
  131. * A `hits` layer containing a feature for each `<field>` value matching the
  132. `geo_bounding_box` query.
  133. * An `aggs` layer containing a feature for each cell of the `geotile_grid`. You
  134. can use these cells as tiles for lower zoom levels. The layer only contains
  135. features for cells with matching data.
  136. * A `meta` layer containing:
  137. ** A feature containing a bounding box. By default, this is the bounding box of
  138. the tile.
  139. ** Value ranges for any sub-aggregations on the `geotile_grid`.
  140. ** Metadata for the search.
  141. The API only returns features that can display at its zoom level. For example,
  142. if a polygon feature has no area at its zoom level, the API omits it.
  143. The API returns errors as UTF-8 encoded JSON.
  144. [[search-vector-tile-api-query-params]]
  145. ==== {api-query-parms-title}
  146. IMPORTANT: You can specify several options for this API as either a query
  147. parameter or request body parameter. If you specify both parameters, the query
  148. parameter takes precedence.
  149. // tag::exact-bounds[]
  150. `exact_bounds`::
  151. (Optional, Boolean)
  152. If `false`, the `meta` layer's feature is the bounding box of the tile. Defaults
  153. to `false`.
  154. +
  155. If `true`, the `meta` layer's feature is a bounding box resulting from a
  156. <<search-aggregations-metrics-geobounds-aggregation,`geo_bounds`>> aggregation.
  157. The aggregation runs on `<field>` values that intersect the `<zoom>/<x>/<y>`
  158. tile with `wrap_longitude` set to `false`. The resulting bounding box may be
  159. larger than the vector tile.
  160. // end::exact-bounds[]
  161. // tag::extent-param[]
  162. `extent`::
  163. (Optional, integer) Size, in pixels, of a side of the tile. Vector tiles are
  164. square with equal sides. Defaults to `4096`.
  165. // end::extent-param[]
  166. // tag::grid-precision[]
  167. `grid_precision`::
  168. (Optional, integer) Additional zoom levels available through the `aggs` layer.
  169. For example, if `<zoom>` is `7` and `grid_precision` is `8`, you can zoom in up to
  170. level 15. Accepts `0`-`8`. Defaults to `8`. If `0`, results don't include the
  171. `aggs` layer.
  172. +
  173. This value determines the grid size of the `geotile_grid` as follows:
  174. +
  175. `(2^grid_precision) x (2^grid_precision)`
  176. +
  177. For example, a value of `8` divides the tile into a grid of 256 x 256 cells. The
  178. `aggs` layer only contains features for cells with matching data.
  179. // end::grid-precision[]
  180. // tag::grid-type[]
  181. `grid_type`::
  182. (Optional, string) Determines the geometry type for features in the `aggs`
  183. layer. In the `aggs` layer, each feature represents a `geotile_grid` cell.
  184. Accepts:
  185. `grid` (Default):::
  186. Each feature is a `Polygon` of the cell's bounding box.
  187. `point`:::
  188. Each feature is a `Point` that's the centroid of the cell.
  189. // end::grid-type[]
  190. // tag::size[]
  191. `size`::
  192. (Optional, integer) Maximum number of features to return in the `hits` layer.
  193. Accepts `0`-`10000`. Defaults to `10000`. If `0`, results don't include the
  194. `hits` layer.
  195. // end::size[]
  196. [role="child_attributes"]
  197. [[search-vector-tile-api-request-body]]
  198. ==== {api-request-body-title}
  199. `aggs`::
  200. (Optional, <<search-aggregations,aggregation object>>)
  201. <<run-sub-aggs,Sub-aggregations>> for the `geotile_grid`. Supports the following
  202. aggregation types:
  203. +
  204. * <<search-aggregations-metrics-avg-aggregation,`avg`>>
  205. * <<search-aggregations-metrics-cardinality-aggregation,`cardinality`>>
  206. * <<search-aggregations-metrics-max-aggregation,`max`>>
  207. * <<search-aggregations-metrics-min-aggregation,`min`>>
  208. * <<search-aggregations-metrics-sum-aggregation,`sum`>>
  209. include::search-vector-tile-api.asciidoc[tag=exact-bounds]
  210. include::search-vector-tile-api.asciidoc[tag=extent-param]
  211. `fields`::
  212. (Optional, array of strings and objects) Fields to return in the `hits` layer.
  213. Supports wildcards (`*`).
  214. +
  215. This parameter does not support fields with <<array,array values>>. Fields with
  216. array values may return inconsistent results.
  217. +
  218. You can specify fields in the array as a string or object.
  219. +
  220. .Properties of `fields` objects
  221. [%collapsible%open]
  222. ====
  223. include::search.asciidoc[tag=fields-api-props]
  224. ====
  225. include::search-vector-tile-api.asciidoc[tag=grid-precision]
  226. include::search-vector-tile-api.asciidoc[tag=grid-type]
  227. `query`::
  228. (Optional, object) <<query-dsl,Query DSL>> used to filter documents for the
  229. search.
  230. include::{es-repo-dir}/search/search.asciidoc[tag=runtime-mappings-def]
  231. include::search-vector-tile-api.asciidoc[tag=size]
  232. `sort`::
  233. (Optional, array of <<sort-search-results,sort objects>>) Sorts features in the
  234. `hits` layer.
  235. +
  236. By default, the API calculates a bounding box for each feature. It sorts
  237. features based on this box's diagonal length, from longest to shortest.
  238. [role="child_attributes"]
  239. [[search-vector-tile-api-response]]
  240. ==== Response
  241. Returned vector tiles contain the following data:
  242. `hits`::
  243. (object) Layer containing results for the `geo_bounding_box` query.
  244. +
  245. .Properties of `hits`
  246. [%collapsible%open]
  247. ====
  248. // tag::extent[]
  249. `extent`::
  250. (integer) Size, in pixels, of a side of the tile. Vector tiles are square with
  251. equal sides.
  252. // end::extent[]
  253. // tag::version[]
  254. `version`::
  255. (integer) Major version number of the
  256. https://github.com/mapbox/vector-tile-spec[Mapbox vector tile specification].
  257. // end::version[]
  258. `features`::
  259. (array of objects) Array of features. Contains a feature for each `<field>`
  260. value that matches the `geo_bounding_box` query.
  261. +
  262. .Properties of `features` objects
  263. [%collapsible%open]
  264. =====
  265. // tag::geometry[]
  266. `geometry`::
  267. (object) Geometry for the feature.
  268. +
  269. .Properties of `geometry`
  270. [%collapsible%open]
  271. ======
  272. `type`::
  273. (string) Geometry type for the feature. Valid values are:
  274. * `UNKNOWN`
  275. * `POINT`
  276. * `LINESTRING`
  277. * `POLYGON`
  278. `coordinates`::
  279. (array of integers or array of arrays) Tile coordinates for the feature.
  280. ======
  281. // end::geometry[]
  282. `properties`::
  283. (object) Properties for the feature.
  284. +
  285. .Properties of `properties`
  286. [%collapsible%open]
  287. ======
  288. `_id`::
  289. (string) Document `_id` for the feature's document.
  290. `<field>`::
  291. Field value. Only returned for fields in the `fields` parameter.
  292. ======
  293. // tag::feature-id[]
  294. `id`::
  295. (integer) Unique ID for the feature within the layer.
  296. // end::feature-id[]
  297. // tag::feature-type[]
  298. `type`::
  299. (integer) Identifier for the feature's geometry type. Values are:
  300. +
  301. * `1` (`POINT`)
  302. * `2` (`LINESTRING`)
  303. * `3` (`POLYGON`)
  304. // end::feature-type[]
  305. =====
  306. ====
  307. `aggs`::
  308. (object) Layer containing results for the `geotile_grid` aggregation and its
  309. sub-aggregations.
  310. +
  311. .Properties of `aggs`
  312. [%collapsible%open]
  313. ====
  314. include::search-vector-tile-api.asciidoc[tag=extent]
  315. include::search-vector-tile-api.asciidoc[tag=version]
  316. `features`::
  317. (array of objects) Array of features. Contains a feature for each cell of the
  318. `geotile_grid`.
  319. +
  320. .Properties of `features` objects
  321. [%collapsible%open]
  322. =====
  323. include::search-vector-tile-api.asciidoc[tag=geometry]
  324. `properties`::
  325. (object) Properties for the feature.
  326. +
  327. .Properties of `properties`
  328. [%collapsible%open]
  329. ======
  330. `_count`::
  331. (string) Count of the cell's documents.
  332. `<sub-aggregation>.value`::
  333. Sub-aggregation results for the cell. Only returned for sub-aggregations in the
  334. `aggs` parameter.
  335. ======
  336. include::search-vector-tile-api.asciidoc[tag=feature-id]
  337. include::search-vector-tile-api.asciidoc[tag=feature-type]
  338. =====
  339. ====
  340. `meta`::
  341. (object) Layer containing metadata for the request.
  342. +
  343. .Properties of `meta`
  344. [%collapsible%open]
  345. ====
  346. include::search-vector-tile-api.asciidoc[tag=extent]
  347. include::search-vector-tile-api.asciidoc[tag=version]
  348. `features`::
  349. (array of objects) Contains a feature for a bounding box.
  350. +
  351. .Properties of `features` objects
  352. [%collapsible%open]
  353. =====
  354. include::search-vector-tile-api.asciidoc[tag=geometry]
  355. `properties`::
  356. (object) Properties for the feature.
  357. +
  358. .Properties of `properties`
  359. [%collapsible%open]
  360. ======
  361. `_shards.failed`::
  362. (integer) Number of shards that failed to execute the search. See the search
  363. API's <<search-api-shards,`shards`>> response property.
  364. `_shards.skipped`::
  365. (integer) Number of shards that skipped the search. See the search
  366. API's <<search-api-shards,`shards`>> response property.
  367. `_shards.successful`::
  368. (integer) Number of shards that executed the search successfully. See the
  369. search API's <<search-api-shards,`shards`>> response property.
  370. `_shards.total`::
  371. (integer) Total number of shards that required querying, including unallocated
  372. shards. See the search API's <<search-api-shards,`shards`>> response property.
  373. `aggregations._count.avg`::
  374. (float) Average `_count` value for features in the `aggs` layer.
  375. `aggregations._count.count`::
  376. (integer) Number of unique `_count` values for features in the `aggs` layer.
  377. `aggregations._count.max`::
  378. (float) Largest `_count` value for features in the `aggs` layer.
  379. `aggregations._count.min`::
  380. (float) Smallest `_count` value for features in the `aggs` layer.
  381. `aggregations._count.sum`::
  382. (float) Sum of `_count` values for features in the `aggs` layer.
  383. `aggregations.<sub-aggregation>.avg`::
  384. (float) Average value for the sub-aggregation's results.
  385. `aggregations.<agg_name>.count`::
  386. (integer) Number of unique values from the sub-aggregation's results.
  387. `aggregations.<agg_name>.max`::
  388. (float) Largest value from the sub-aggregation's results.
  389. `aggregations.<agg_name>.min`::
  390. (float) Smallest value from the sub-aggregation's results.
  391. `aggregations.<agg_name>.sum`::
  392. (float) Sum of values for the sub-aggregation's results.
  393. `hits.max_score`::
  394. (float) Highest document `_score` for the search's hits.
  395. `hits.total.relation`::
  396. (string) Indicates whether `hits.total.value` is accurate or a lower bound.
  397. Possible values are:
  398. `eq`::: Accurate
  399. `gte`::: Lower bound
  400. `hits.total.value`::
  401. (integer) Total number of hits for the search.
  402. `timed_out`::
  403. (Boolean) If `true`, the search timed out before completion. Results may be
  404. partial or empty.
  405. `took`::
  406. (integer) Milliseconds it took {es} to run the search. See the search API's
  407. <<search-api-took,`took`>> response property.
  408. ======
  409. include::search-vector-tile-api.asciidoc[tag=feature-id]
  410. include::search-vector-tile-api.asciidoc[tag=feature-type]
  411. =====
  412. ====
  413. [[search-vector-tile-api-api-example]]
  414. ==== {api-examples-title}
  415. The following requests create the `museum` index and add several geospatial
  416. `location` values.
  417. [source,console]
  418. ----
  419. PUT museums
  420. {
  421. "mappings": {
  422. "properties": {
  423. "location": {
  424. "type": "geo_point"
  425. },
  426. "name": {
  427. "type": "keyword"
  428. },
  429. "price": {
  430. "type": "long"
  431. },
  432. "included": {
  433. "type": "boolean"
  434. }
  435. }
  436. }
  437. }
  438. POST museums/_bulk?refresh
  439. { "index": { "_id": "1" } }
  440. { "location": "52.374081,4.912350", "name": "NEMO Science Museum", "price": 1750, "included": true }
  441. { "index": { "_id": "2" } }
  442. { "location": "52.369219,4.901618", "name": "Museum Het Rembrandthuis", "price": 1500, "included": false }
  443. { "index": { "_id": "3" } }
  444. { "location": "52.371667,4.914722", "name": "Nederlands Scheepvaartmuseum", "price":1650, "included": true }
  445. { "index": { "_id": "4" } }
  446. { "location": "52.371667,4.914722", "name": "Amsterdam Centre for Architecture", "price":0, "included": true }
  447. ----
  448. The following request searches the index for `location` values that intersect
  449. the `13/4207/2692` vector tile.
  450. [source,console]
  451. ----
  452. GET museums/_mvt/location/13/4207/2692
  453. {
  454. "grid_precision": 2,
  455. "fields": [
  456. "name",
  457. "price"
  458. ],
  459. "query": {
  460. "term": {
  461. "included": true
  462. }
  463. },
  464. "aggs": {
  465. "min_price": {
  466. "min": {
  467. "field": "price"
  468. }
  469. },
  470. "max_price": {
  471. "max": {
  472. "field": "price"
  473. }
  474. },
  475. "avg_price": {
  476. "avg": {
  477. "field": "price"
  478. }
  479. }
  480. }
  481. }
  482. ----
  483. // TEST[continued]
  484. The API returns results as a binary vector tile. When decoded into JSON, the
  485. tile contains the following data:
  486. [source,js]
  487. ----
  488. {
  489. "hits": {
  490. "extent": 4096,
  491. "version": 2,
  492. "features": [
  493. {
  494. "geometry": {
  495. "type": "Point",
  496. "coordinates": [
  497. 3208,
  498. 3864
  499. ]
  500. },
  501. "properties": {
  502. "_id": "1",
  503. "name": "NEMO Science Museum",
  504. "price": 1750
  505. },
  506. "id": 0,
  507. "type": 1
  508. },
  509. {
  510. "geometry": {
  511. "type": "Point",
  512. "coordinates": [
  513. 3429,
  514. 3496
  515. ]
  516. },
  517. "properties": {
  518. "_id": "3",
  519. "name": "Nederlands Scheepvaartmuseum",
  520. "price": 1650
  521. },
  522. "id": 0,
  523. "type": 1
  524. },
  525. {
  526. "geometry": {
  527. "type": "Point",
  528. "coordinates": [
  529. 3429,
  530. 3496
  531. ]
  532. },
  533. "properties": {
  534. "_id": "4",
  535. "name": "Amsterdam Centre for Architecture",
  536. "price": 0
  537. },
  538. "id": 0,
  539. "type": 1
  540. }
  541. ]
  542. },
  543. "aggs": {
  544. "extent": 4096,
  545. "version": 2,
  546. "features": [
  547. {
  548. "geometry": {
  549. "type": "Polygon",
  550. "coordinates": [
  551. [
  552. [
  553. 3072,
  554. 3072
  555. ],
  556. [
  557. 4096,
  558. 3072
  559. ],
  560. [
  561. 4096,
  562. 4096
  563. ],
  564. [
  565. 3072,
  566. 4096
  567. ],
  568. [
  569. 3072,
  570. 3072
  571. ]
  572. ]
  573. ]
  574. },
  575. "properties": {
  576. "_count": 3,
  577. "max_price.value": 1750.0,
  578. "min_price.value": 0.0,
  579. "avg_price.value": 1133.3333333333333
  580. },
  581. "id": 0,
  582. "type": 3
  583. }
  584. ]
  585. },
  586. "meta": {
  587. "extent": 4096,
  588. "version": 2,
  589. "features": [
  590. {
  591. "geometry": {
  592. "type": "Polygon",
  593. "coordinates": [
  594. [
  595. [
  596. 0,
  597. 0
  598. ],
  599. [
  600. 4096,
  601. 0
  602. ],
  603. [
  604. 4096,
  605. 4096
  606. ],
  607. [
  608. 0,
  609. 4096
  610. ],
  611. [
  612. 0,
  613. 0
  614. ]
  615. ]
  616. ]
  617. },
  618. "properties": {
  619. "_shards.failed": 0,
  620. "_shards.skipped": 0,
  621. "_shards.successful": 1,
  622. "_shards.total": 1,
  623. "aggregations._count.avg": 3.0,
  624. "aggregations._count.count": 1,
  625. "aggregations._count.max": 3.0,
  626. "aggregations._count.min": 3.0,
  627. "aggregations._count.sum": 3.0,
  628. "aggregations.avg_price.avg": 1133.3333333333333,
  629. "aggregations.avg_price.count": 1,
  630. "aggregations.avg_price.max": 1133.3333333333333,
  631. "aggregations.avg_price.min": 1133.3333333333333,
  632. "aggregations.avg_price.sum": 1133.3333333333333,
  633. "aggregations.max_price.avg": 1750.0,
  634. "aggregations.max_price.count": 1,
  635. "aggregations.max_price.max": 1750.0,
  636. "aggregations.max_price.min": 1750.0,
  637. "aggregations.max_price.sum": 1750.0,
  638. "aggregations.min_price.avg": 0.0,
  639. "aggregations.min_price.count": 1,
  640. "aggregations.min_price.max": 0.0,
  641. "aggregations.min_price.min": 0.0,
  642. "aggregations.min_price.sum": 0.0,
  643. "hits.max_score": 0.0,
  644. "hits.total.relation": "eq",
  645. "hits.total.value": 3,
  646. "timed_out": false,
  647. "took": 2
  648. },
  649. "id": 0,
  650. "type": 3
  651. }
  652. ]
  653. }
  654. }
  655. ----
  656. // NOTCONSOLE