Geoshape query

Use a geoshape query to search for documents that contain geopoint or geoshape fields. You can filter documents using a geoshape that is defined within a query or use a pre-indexed geoshape.

The searched document field must be mapped as geo_point or geo_shape.

Spatial relations

When you provide a geoshape to the geoshape query, the geopoint and geoshape fields in the documents are matched using the following spatial relations to the provided shape.

RelationDescriptionSupporting geographic field type
INTERSECTS(Default) Matches documents whose geopoint or geoshape intersects with the shape provided in the query.geo_point, geo_shape
DISJOINTMatches documents whose geoshape does not intersect with the shape provided in the query.geo_shape
WITHINMatches documents whose geoshape is completely within the shape provided in the query.geo_shape
CONTAINSMatches documents whose geoshape completely contains the shape provided in the query.geo_shape

Defining the shape in a geoshape query

You can define the shape to filter documents in a geoshape query either by providing a new shape definition at query time or by referencing the name of a shape pre-indexed in another index.

Using a new shape definition

To provide a new shape to a geoshape query, define it in the geo_shape field. You must define the geoshape in GeoJSON format.

The following example illustrates searching for documents containing geoshapes that match a geoshape defined at query time.

Step 1: Create an index

First, create an index and map the location field as a geo_shape:

  1. PUT /testindex
  2. {
  3. "mappings": {
  4. "properties": {
  5. "location": {
  6. "type": "geo_shape"
  7. }
  8. }
  9. }
  10. }

copy

Step 2: Index documents

Index one document containing a point and another containing a polygon:

  1. PUT testindex/_doc/1
  2. {
  3. "location": {
  4. "type": "point",
  5. "coordinates": [ 73.0515, 41.5582 ]
  6. }
  7. }

copy

  1. PUT testindex/_doc/2
  2. {
  3. "location": {
  4. "type": "polygon",
  5. "coordinates": [
  6. [
  7. [
  8. 73.0515,
  9. 41.5582
  10. ],
  11. [
  12. 72.6506,
  13. 41.5623
  14. ],
  15. [
  16. 72.6734,
  17. 41.7658
  18. ],
  19. [
  20. 73.0515,
  21. 41.5582
  22. ]
  23. ]
  24. ]
  25. }
  26. }

copy

Step 3: Run a geoshape query

Finally, define a geoshape to filter the documents. The following sections illustrate providing various geoshapes in a query. For more information about various geoshape formats, see Geoshape field type.

Envelope

An envelope is a bounding rectangle in the [[minLon, maxLat], [maxLon, minLat]] format. Search for documents containing geoshape fields that intersect with the provided envelope:

  1. GET /testindex/_search
  2. {
  3. "query": {
  4. "geo_shape": {
  5. "location": {
  6. "shape": {
  7. "type": "envelope",
  8. "coordinates": [
  9. [
  10. 71.0589,
  11. 42.3601
  12. ],
  13. [
  14. 74.006,
  15. 40.7128
  16. ]
  17. ]
  18. },
  19. "relation": "WITHIN"
  20. }
  21. }
  22. }
  23. }

copy

The response contains both documents:

  1. {
  2. "took": 5,
  3. "timed_out": false,
  4. "_shards": {
  5. "total": 1,
  6. "successful": 1,
  7. "skipped": 0,
  8. "failed": 0
  9. },
  10. "hits": {
  11. "total": {
  12. "value": 2,
  13. "relation": "eq"
  14. },
  15. "max_score": 0,
  16. "hits": [
  17. {
  18. "_index": "testindex",
  19. "_id": "1",
  20. "_score": 0,
  21. "_source": {
  22. "location": {
  23. "type": "point",
  24. "coordinates": [
  25. 73.0515,
  26. 41.5582
  27. ]
  28. }
  29. }
  30. },
  31. {
  32. "_index": "testindex",
  33. "_id": "2",
  34. "_score": 0,
  35. "_source": {
  36. "location": {
  37. "type": "polygon",
  38. "coordinates": [
  39. [
  40. [
  41. 73.0515,
  42. 41.5582
  43. ],
  44. [
  45. 72.6506,
  46. 41.5623
  47. ],
  48. [
  49. 72.6734,
  50. 41.7658
  51. ],
  52. [
  53. 73.0515,
  54. 41.5582
  55. ]
  56. ]
  57. ]
  58. }
  59. }
  60. }
  61. ]
  62. }
  63. }

Point

Search for documents whose geoshape fields contain the provided point:

  1. GET /testindex/_search
  2. {
  3. "query": {
  4. "geo_shape": {
  5. "location": {
  6. "shape": {
  7. "type": "point",
  8. "coordinates": [
  9. 72.8000,
  10. 41.6300
  11. ]
  12. },
  13. "relation": "CONTAINS"
  14. }
  15. }
  16. }
  17. }

copy

Linestring

Search for documents whose geoshape fields do not intersect with the provided linestring:

  1. GET /testindex/_search
  2. {
  3. "query": {
  4. "geo_shape": {
  5. "location": {
  6. "shape": {
  7. "type": "linestring",
  8. "coordinates": [[74.0060, 40.7128], [71.0589, 42.3601]]
  9. },
  10. "relation": "DISJOINT"
  11. }
  12. }
  13. }
  14. }

copy

Linestring geoshape queries do not support the WITHIN relation.

Polygon

In GeoJSON format, you must list the vertices of the polygon in counterclockwise order and close the polygon so that the first vertex and the last vertex are the same.

Search for documents whose geoshape fields are within the provided polygon:

  1. GET /testindex/_search
  2. {
  3. "query": {
  4. "geo_shape": {
  5. "location": {
  6. "shape": {
  7. "type": "polygon",
  8. "coordinates": [
  9. [
  10. [74.0060, 40.7128],
  11. [73.7562, 42.6526],
  12. [71.0589, 42.3601],
  13. [74.0060, 40.7128]
  14. ]
  15. ]
  16. },
  17. "relation": "WITHIN"
  18. }
  19. }
  20. }
  21. }

copy

Multipoint

Search for documents whose geoshape fields do not intersect with the provided points:

  1. GET /testindex/_search
  2. {
  3. "query": {
  4. "geo_shape": {
  5. "location": {
  6. "shape": {
  7. "type": "multipoint",
  8. "coordinates" : [
  9. [74.0060, 40.7128],
  10. [71.0589, 42.3601]
  11. ]
  12. },
  13. "relation": "DISJOINT"
  14. }
  15. }
  16. }
  17. }

copy

Multilinestring

Search for documents whose geoshape fields do not intersect with the provided lines:

  1. GET /testindex/_search
  2. {
  3. "query": {
  4. "geo_shape": {
  5. "location": {
  6. "shape": {
  7. "type": "multilinestring",
  8. "coordinates" : [
  9. [[74.0060, 40.7128], [71.0589, 42.3601]],
  10. [[73.7562, 42.6526], [72.6734, 41.7658]]
  11. ]
  12. },
  13. "relation": "disjoint"
  14. }
  15. }
  16. }
  17. }

copy

Multilinestring geoshape queries do not support the WITHIN relation.

Multipolygon

Search for documents whose geoshape fields are within the provided multipolygon:

  1. GET /testindex/_search
  2. {
  3. "query": {
  4. "geo_shape": {
  5. "location": {
  6. "shape": {
  7. "type" : "multipolygon",
  8. "coordinates" : [
  9. [
  10. [
  11. [74.0060, 40.7128],
  12. [73.7562, 42.6526],
  13. [71.0589, 42.3601],
  14. [74.0060, 40.7128]
  15. ],
  16. [
  17. [73.0515, 41.5582],
  18. [72.6506, 41.5623],
  19. [72.6734, 41.7658],
  20. [73.0515, 41.5582]
  21. ]
  22. ],
  23. [
  24. [
  25. [73.9146, 40.8252],
  26. [73.8871, 41.0389],
  27. [73.6853, 40.9747],
  28. [73.9146, 40.8252]
  29. ]
  30. ]
  31. ]
  32. },
  33. "relation": "WITHIN"
  34. }
  35. }
  36. }
  37. }

copy

Geometry collection

Search for documents whose geoshape fields are within the provided polygons:

  1. GET /testindex/_search
  2. {
  3. "query": {
  4. "geo_shape": {
  5. "location": {
  6. "shape": {
  7. "type": "geometrycollection",
  8. "geometries": [
  9. {
  10. "type": "polygon",
  11. "coordinates": [[
  12. [74.0060, 40.7128],
  13. [73.7562, 42.6526],
  14. [71.0589, 42.3601],
  15. [74.0060, 40.7128]
  16. ]]
  17. },
  18. {
  19. "type": "polygon",
  20. "coordinates": [[
  21. [73.0515, 41.5582],
  22. [72.6506, 41.5623],
  23. [72.6734, 41.7658],
  24. [73.0515, 41.5582]
  25. ]]
  26. }
  27. ]
  28. },
  29. "relation": "WITHIN"
  30. }
  31. }
  32. }
  33. }

copy

Geoshape queries whose geometry collection contains a linestring or a multilinestring do not support the WITHIN relation.

Using a pre-indexed shape definition

When constructing a geoshape query, you can also reference the name of a shape pre-indexed in another index. Using this method, you can define a geoshape at index time and refer to it by name at search time.

You can define a pre-indexed geoshape in GeoJSON or Well-Known Text (WKT) format. For more information about various geoshape formats, see Geoshape field type.

The indexed_shape object supports the following parameters.

ParameterRequired/OptionalDescription
idRequiredThe document ID of the document containing the pre-indexed shape.
indexOptionalThe name of the index containing the pre-indexed shape. Default is shapes.
pathOptionalThe field name of the field containing the pre-indexed shape as a path. Default is shape.
routingOptionalThe routing of the document containing the pre-indexed shape.

The following example illustrates how to reference the name of a shape pre-indexed in another index. In this example, the index pre-indexed-shapes contains the shape that defines the boundaries, and the index testindex contains the shapes that are checked against those boundaries.

First, create the pre-indexed-shapes index and map the boundaries field for this index as a geo_shape:

  1. PUT /pre-indexed-shapes
  2. {
  3. "mappings": {
  4. "properties": {
  5. "boundaries": {
  6. "type": "geo_shape",
  7. "orientation" : "left"
  8. }
  9. }
  10. }
  11. }

copy

For more information about specifying a different vertex orientation for polygons, see Polygon.

Index a polygon specifying the search boundaries into the pre-indexed-shapes index. The polygon’s ID is search_triangle. In this example, you’ll index the polygon in WKT format:

  1. PUT /pre-indexed-shapes/_doc/search_triangle
  2. {
  3. "boundaries":
  4. "POLYGON ((74.0060 40.7128, 71.0589 42.3601, 73.7562 42.6526, 74.0060 40.7128))"
  5. }

copy

If you haven’t already done so, index one document containing a point and another document containing a polygon into the testindex index:

  1. PUT /testindex/_doc/1
  2. {
  3. "location": {
  4. "type": "point",
  5. "coordinates": [ 73.0515, 41.5582 ]
  6. }
  7. }

copy

  1. PUT /testindex/_doc/2
  2. {
  3. "location": {
  4. "type": "polygon",
  5. "coordinates": [
  6. [
  7. [
  8. 73.0515,
  9. 41.5582
  10. ],
  11. [
  12. 72.6506,
  13. 41.5623
  14. ],
  15. [
  16. 72.6734,
  17. 41.7658
  18. ],
  19. [
  20. 73.0515,
  21. 41.5582
  22. ]
  23. ]
  24. ]
  25. }
  26. }

copy

Search for documents whose geoshapes are within the search_triangle:

  1. GET /testindex/_search
  2. {
  3. "query": {
  4. "bool": {
  5. "must": {
  6. "match_all": {}
  7. },
  8. "filter": {
  9. "geo_shape": {
  10. "location": {
  11. "indexed_shape": {
  12. "index": "pre-indexed-shapes",
  13. "id": "search_triangle",
  14. "path": "boundaries"
  15. },
  16. "relation": "WITHIN"
  17. }
  18. }
  19. }
  20. }
  21. }
  22. }

copy

The response contains both documents:

  1. {
  2. "took": 11,
  3. "timed_out": false,
  4. "_shards": {
  5. "total": 1,
  6. "successful": 1,
  7. "skipped": 0,
  8. "failed": 0
  9. },
  10. "hits": {
  11. "total": {
  12. "value": 2,
  13. "relation": "eq"
  14. },
  15. "max_score": 1,
  16. "hits": [
  17. {
  18. "_index": "testindex",
  19. "_id": "1",
  20. "_score": 1,
  21. "_source": {
  22. "location": {
  23. "type": "point",
  24. "coordinates": [
  25. 73.0515,
  26. 41.5582
  27. ]
  28. }
  29. }
  30. },
  31. {
  32. "_index": "testindex",
  33. "_id": "2",
  34. "_score": 1,
  35. "_source": {
  36. "location": {
  37. "type": "polygon",
  38. "coordinates": [
  39. [
  40. [
  41. 73.0515,
  42. 41.5582
  43. ],
  44. [
  45. 72.6506,
  46. 41.5623
  47. ],
  48. [
  49. 72.6734,
  50. 41.7658
  51. ],
  52. [
  53. 73.0515,
  54. 41.5582
  55. ]
  56. ]
  57. ]
  58. }
  59. }
  60. }
  61. ]
  62. }
  63. }

Querying geopoints

You can also use a geoshape query to search for documents containing geopoints.

Geoshape queries on geopoint fields only support the default INTERSECTS spatial relation, so you don’t need to provide the relation parameter.

Geoshape queries on geopoint fields do not support the following geoshapes:

  • Points
  • Linestrings
  • Multipoints
  • Multilinestrings
  • Geometry collections containing one of the preceding geoshape types

Create a mapping where location is a geo_point:

  1. PUT /testindex1
  2. {
  3. "mappings": {
  4. "properties": {
  5. "location": {
  6. "type": "geo_point"
  7. }
  8. }
  9. }
  10. }

copy

Index two points into the index. In this example, you’ll provide the geopoint coordinates as strings:

  1. PUT /testindex1/_doc/1
  2. {
  3. "location": "41.5623, 72.6506"
  4. }

copy

  1. PUT /testindex1/_doc/2
  2. {
  3. "location": "76.0254, 39.2467"
  4. }

copy

For information about providing geopoint coordinates in various formats, see Formats.

Search for geopoints that intersect with the provided polygon:

  1. GET /testindex1/_search
  2. {
  3. "query": {
  4. "geo_shape": {
  5. "location": {
  6. "shape": {
  7. "type": "polygon",
  8. "coordinates": [
  9. [
  10. [74.0060, 40.7128],
  11. [73.7562, 42.6526],
  12. [71.0589, 42.3601],
  13. [74.0060, 40.7128]
  14. ]
  15. ]
  16. }
  17. }
  18. }
  19. }
  20. }

copy

The response returns document 1:

  1. {
  2. "took": 21,
  3. "timed_out": false,
  4. "_shards": {
  5. "total": 1,
  6. "successful": 1,
  7. "skipped": 0,
  8. "failed": 0
  9. },
  10. "hits": {
  11. "total": {
  12. "value": 1,
  13. "relation": "eq"
  14. },
  15. "max_score": 0,
  16. "hits": [
  17. {
  18. "_index": "testindex1",
  19. "_id": "1",
  20. "_score": 0,
  21. "_source": {
  22. "location": "41.5623, 72.6506"
  23. }
  24. }
  25. ]
  26. }
  27. }

Note that when you indexed the geopoints, you specified their coordinates in "latitude, longitude" format. When you search for matching documents, the coordinate array is in [longitude, latitude] format. Thus, document 1 is returned in the results but document 2 is not.

Request fields

Geoshape queries accept the following fields.

FieldData typeDescription
ignore_unmappedBooleanSpecifies whether to ignore an unmapped field. If set to true, then the query does not return any documents that contain an unmapped field. If set to false, then an exception is thrown when the field is unmapped. Optional. Default is false.