geoShape Operator

For the complete MongoDB documentation index, see www.mongodb.com/docs/llms.txt

geoShape Operator

Definition

The geoShape operator supports querying shapes with a relation to a given geometry if indexShapes is set to true in the [index definition.](https://www.mongodb.com/docs/search/indexes/field-types/geo-type.md#std-label-bson-data-types-geo

When specifying the coordinates to search, longitude must be specified first and then the latitude. Longitude values can be between -180 and 180, both inclusive. Latitude values can be between -90 and 90, both inclusive. Coordinate values can be integers or doubles.

Note:

MongoDB Search does not support the following:

  • Non-default coordinate reference system (CRS)

  • Planar XY coordinate system (2 dimensional)

  • Coordinate pairs Point notation (that is, pointFieldName: [12, 34])

Syntax

{
    "$search": {
       "index": <index name>, // optional, defaults to "default"
       "geoShape": {
          "path": "<field-to-search>",
          "relation": "contains | disjoint | intersects | within",
          "geometry": <GeoJSON-object>,
          "score": <score-options>
       }
    }
}

Options

geoShape uses the following terms to construct a query:

Field Type Description Necessity
geometry GeoJSON object [GeoJSON](https://www.mongodb.com/docs/manual/reference/geojson.md#std-label-geospatial-indexes-store-geojson object that specifies the [Polygon](https://www.mongodb.com/docs/manual/reference/geojson.md#std-label-geojson-polygon, [MultiPolygon](https://www.mongodb.com/docs/manual/reference/geojson.md#std-label-geojson-multipolygon, or [LineString](https://www.mongodb.com/docs/manual/reference/geojson.md#std-label-geojson-linestring shape or point to search. The polygon must be specified as a closed loop where the last position is the same as the first position. When calculating geospatial results, MongoDB Search [geoShape](https://www.mongodb.com/docs/search/query/operators-collectors/geoshape.md#std-label-geoshape-ref and [geoWithin](https://www.mongodb.com/docs/search/query/operators-collectors/geowithin.md#std-label-geowithin-ref operators and MongoDB $geoIntersects operator use different geometries. This difference can be seen in how MongoDB Search and MongoDB draw polygonal edges. MongoDB Search draws polygons based on Cartesian distance, which is the shortest line between two points in the coordinate reference system. MongoDB draws polygons using the geodesic mode based on 2dsphere indexes that is built on top of a third-party library for geodesic types, or the flat mode, from 2d indexes. To learn more, see [GeoJSON Objects.](https://www.mongodb.com/docs/manual/reference/geojson/#polygon MongoDB Search and MongoDB could return different results for geospatial queries involving polygons. yes
path string or array of strings Indexed [geo](https://www.mongodb.com/docs/search/indexes/field-types/geo-type.md#std-label-bson-data-types-geo type field or fields to search. yes
relation enum Relation of the query shape geometry to the indexed field geometry. Value can be one of the following: contains - Indicates that the indexed geometry contains the query geometry.; disjoint - Indicates that both the query and indexed geometries have nothing in common.; intersects - Indicates that both the query and indexed geometries intersect.; within - Indicates that the indexed geometry is within the query geometry. You can't use within with LineString or Point. yes
score object Score to assign to matching search results. By default, the [score](https://www.mongodb.com/docs/search/query/score/overview.md#std-label-scoring-ref in the results is 1. You can modify the score using the following options: boost: multiply the result score by the given number.; constant: replace the result score with the given number.; function: replace the result score with the given expression. For information on using score in your query, see [Score the Documents in the Results.](https://www.mongodb.com/docs/search/query/score/overview.md#std-label-scoring-ref no

Examples

The following examples use the listingsAndReviews collection in the sample_airbnb database. If you have the [sample dataset](https://www.mongodb.com/docs/manual/sample-data.md#std-label-available-sample-datasets on your cluster, you can create a custom MongoDB Search index for [geo](https://www.mongodb.com/docs/search/indexes/field-types/geo-type.md#std-label-bson-data-types-geo type and run the example queries on your cluster. The [MongoDB Search Quick Start](https://www.mongodb.com/docs/search/tutorial.md#std-label-fts-tutorial-ref contains instructions for loading the [sample dataset](https://www.mongodb.com/docs/manual/sample-data.md#std-label-available-sample-datasets, creating an [index definition](https://www.mongodb.com/docs/search/indexes/index-definitions.md#std-label-ref-index-definitions, and running MongoDB Search queries.

The following is a sample index definition for indexing the address.location field in the listingsAndReviews collection:

{
  "mappings": {
    "fields": {
      "address": {
        "fields": {
          "location": {
            "indexShapes": true,
            "type": "geo"
          }
        },
        "type": "document"
      },
      "property_type": {
        "type": "token"
      }
    }
  }
}

Disjoint Example

The following example uses the geoShape operator to search for properties that have nothing in common with the specified longitude and latitude coordinates in Hawaii.

The query includes a:

  • [$limit](https://www.mongodb.com/docs/manual/reference/operator/aggregation/limit.md#mongodb-pipeline-pipe.-limit stage to limit the output to 3 results.

  • [$project](https://www.mongodb.com/docs/manual/reference/operator/aggregation/project.md#mongodb-pipeline-pipe.-project stage to exclude all fields except name and address.

db.listingsAndReviews.aggregate([
  {
    "$search": {
      "geoShape": {
        "relation": "disjoint",
        "geometry": {
          "type": "Polygon",
          "coordinates": [[[-161.323242,22.512557],
                          [-152.446289,22.065278],
                          [-156.09375,17.811456],
                          [-161.323242,22.512557]]]
        },
        "path": "address.location"
      }
    }
  },
  {
    $limit: 3
  },
  {
    $project: {
      "_id": 0,
      "name": 1,
      "address": 1,
      score: { $meta: "searchScore" }
    }
  }
])

Output:

{
  "name" : "Ribeira Charming Duplex",
  "address" : {
    "street" : "Porto, Porto, Portugal",
    "suburb" : "",
    "government_area" : "Cedofeita, Ildefonso, Sé, Miragaia, Nicolau, Vitória",
    "market" : "Porto",
    "country" : "Portugal",
    "country_code" : "PT",
    "location" : {
      "type" : "Point",
      "coordinates" : [ -8.61308, 41.1413 ],
      "is_location_exact" : false
    }
  }
}
{
  "name" : "Horto flat with small garden",
  "address" : {
    "street" : "Rio de Janeiro, Rio de Janeiro, Brazil",
    "suburb" : "Jardim Botânico",
    "government_area" : "Jardim Botânico",
    "market" : "Rio De Janeiro",
    "country" : "Brazil",
    "country_code" : "BR",
    "location" : {
      "type" : "Point",
      "coordinates" : [ -43.23074991429229, -22.966253551739655 ],
      "is_location_exact" : true
    }
  }
}
{
  "name" : "Private Room in Bushwick",
  "address" : {
    "street" : "Brooklyn, NY, United States",
    "suburb" : "Brooklyn",
    "government_area" : "Bushwick",
    "market" : "New York",
    "country" : "United States",
    "country_code" : "US",
    "location" : {
      "type" : "Point",
      "coordinates" : [ -73.93615, 40.69791 ],
      "is_location_exact" : true
    }
  }
}

Intersects Example

The following example uses the geoShape operator to search for properties that intersect with the specified longitude and latitude coordinates in Spain.

The query includes a:

  • [$limit](https://www.mongodb.com/docs/manual/reference/operator/aggregation/limit.md#mongodb-pipeline-pipe.-limit stage to limit the output to 3 results.

  • [$project](https://www.mongodb.com/docs/manual/reference/operator/aggregation/project.md#mongodb-pipeline-pipe.-project stage to exclude all fields except name and address.

db.listingsAndReviews.aggregate([
  {
    "$search": {
      "geoShape": {
        "relation": "intersects",
        "geometry": {
          "type": "MultiPolygon",
          "coordinates": [
                        [[[2.16942,41.40082],
                        [2.17963,41.40087],
                        [2.18146,41.39716],
                        [2.15533,41.40686],
                        [2.14596,41.38475],
                        [2.17519,41.41035],
                        [2.16942,41.40082]]],
                        [[[2.16365,41.39416],
                        [2.16963,41.39726],
                        [2.15395,41.38005],
                        [2.17935,41.43038],
                        [2.16365,41.39416]]]
          ]
        },
        "path": "address.location"
      }
    }
  },
  {
    $limit: 3
  },
  {
    $project: {
      "_id": 0,
      "name": 1,
      "address": 1,
      score: { $meta: "searchScore" }
    }
  }
])

Output:

{
  "name" : "Cozy bedroom Sagrada Familia",
  "address" : {
    "street" : "Barcelona, Catalunya, Spain",
    "suburb" : "Eixample",
    "government_area" : "el Fort Pienc",
    "market" : "Barcelona",
    "country" : "Spain",
    "country_code" : "ES",
    "location" : {
      "type" : "Point",
      "coordinates" : [ 2.17963, 41.40087 ],
      "is_location_exact" : true
    }
  }
}
{
  "name" : "",
  "address" : {
    "street" : "Barcelona, Catalunya, Spain",
    "suburb" : "Vila de Gràcia",
    "government_area" : "la Vila de Gràcia",
    "market" : "Barcelona",
    "country" : "Spain",
    "country_code" : "ES",
    "location" : {
      "type" : "Point",
      "coordinates" : [ 2.15759, 41.40349 ],
      "is_location_exact" : true
    }
  }
}
{
  "name" : "SPACIOUS RAMBLA CATALUÑA",
  "address" : {
    "street" : "Barcelona, Catalunya, Spain",
    "suburb" : "L'Antiga Esquerra de l'Eixample",
    "government_area" : "l'Antiga Esquerra de l'Eixample",
    "market" : "Barcelona",
    "country" : "Spain",
    "country_code" : "ES",
    "location" : {
      "type" : "Point",
      "coordinates" : [ 2.15255, 41.39193 ],
      "is_location_exact" : true
    }
  }
}

Within Example

The following example uses the geoShape operator to search for properties in New York that are within the specified longitude and latitude coordinates. The queries searches the address.location field in the listingsAndReviews collection in the sample_airbnb database.

The query includes a:

  • [$limit](https://www.mongodb.com/docs/manual/reference/operator/aggregation/limit.md#mongodb-pipeline-pipe.-limit stage to limit the output to 3 results.

  • [$project](https://www.mongodb.com/docs/manual/reference/operator/aggregation/project.md#mongodb-pipeline-pipe.-project stage to exclude all fields except name and address.

The following query returns the documents that match the specified search criteria.

db.listingsAndReviews.aggregate([
  {
    "$search": {
      "geoShape": {
        "relation": "within",
        "geometry": {
          "type": "Polygon",
          "coordinates": [[[-74.3994140625,40.5305017757],
                          [-74.7290039063,40.5805846641],
                          [-74.7729492188,40.9467136651],
                          [-74.0698242188,41.1290213475],
                          [-73.65234375,40.9964840144],
                          [-72.6416015625,40.9467136651],
                          [-72.3559570313,40.7971774152],
                          [-74.3994140625,40.5305017757]]]
        },
        "path": "address.location"
      }
    }
  },
  {
    $limit: 3
  },
  {
    $project: {
      "_id": 0,
      "name": 1,
      "address": 1,
      score: { $meta: "searchScore" }
    }
  }
])

Output:

{
  "name" : "Private Room in Bushwick",
  "address" : {
    "street" : "Brooklyn, NY, United States",
    "suburb" : "Brooklyn",
    "government_area" : "Bushwick",
    "market" : "New York",
    "country" : "United States",
    "country_code" : "US",
    "location" : {
      "type" : "Point",
      "coordinates" : [ -73.93615, 40.69791 ],
      "is_location_exact" : true
    }
  },
  {
    "name" : "New York City - Upper West Side Apt",
    "address" : {
      "street" : "New York, NY, United States",
      "suburb" : "Manhattan",
      "government_area" : "Upper West Side",
      "market" : "New York",
      "country" : "United States",
      "country_code" : "US",
      "location" : {
        "type" : "Point",
        "coordinates" : [ -73.96523, 40.79962 ],
        "is_location_exact" : false
      }
    },
    "score" : 1
  }
  {
    "name" : "Deluxe Loft Suite",
    "address" : {
      "street" : "Brooklyn, NY, United States",
      "suburb" : "Greenpoint",
      "government_area" : "Greenpoint",
      "market" : "New York",
      "country" : "United States",
      "country_code" : "US",
      "location" : {
        "type" : "Point",
        "coordinates" : [ -73.94472, 40.72778 ],
        "is_location_exact" : true
      }
    },
    "score" : 1
  }

The following query returns the number of types of properties (such as apartment, house, and so on) for the specified search criteria.

db.listingsAndReviews.aggregate([
  {
    "$searchMeta": {
      "facet": {
        "operator": {
          "geoShape": {
          "relation": "within",
          "geometry": {
            "type": "Polygon",
            "coordinates": [[[-74.3994140625,40.5305017757],
                            [-74.7290039063,40.5805846641],
                            [-74.7729492188,40.9467136651],
                            [-74.0698242188,41.1290213475],
                            [-73.65234375,40.9964840144],
                            [-72.6416015625,40.9467136651],
                            [-72.3559570313,40.7971774152],
                            [-74.3994140625,40.5305017757]]]
          },
          "path": "address.location"
        }
        },
        "facets": {
          "propertyTypeFacet": {
            "type": "string",
            "path": "property_type"
          }
        }
      }
    }
  }
])

Output:

[
  {
    count: { lowerBound: Long('599') },
    facet: {
      propertyTypeFacet: {
        buckets: [
          { _id: 'Apartment', count: Long('486') },
          { _id: 'House', count: Long('43') },
          { _id: 'Townhouse', count: Long('24') },
          { _id: 'Condominium', count: Long('19') },
          { _id: 'Loft', count: Long('19') },
          { _id: 'Guest suite', count: Long('2') },
          { _id: 'Guesthouse', count: Long('2') },
          { _id: 'Aparthotel', count: Long('1') },
          { _id: 'Hostel', count: Long('1') },
          { _id: 'Serviced apartment', count: Long('1') }
        ]
      }
    }
  }
]

The query results show the different types of properties in the specified coordinates.