Geospatial Queries¶
MongoDB supports query operations on geospatial data. This section introduces MongoDB’s geospatial features.
Geospatial Data¶
In MongoDB, you can store geospatial data as GeoJSON objects or as legacy coordinate pairs.
GeoJSON Objects¶
To calculate geometry over an Earth-like sphere, store your location data as GeoJSON objects.
To specify GeoJSON data, use an embedded document with:
a field named
type
that specifies the GeoJSON object type anda field named
coordinates
that specifies the object’s coordinates.If specifying latitude and longitude coordinates, list the longitude first and then latitude:
- Valid longitude values are between
-180
and180
, both inclusive. - Valid latitude values are between
-90
and90
(both inclusive).
- Valid longitude values are between
<field>: { type: <GeoJSON type> , coordinates: <coordinates> }
For example, to specify a GeoJSON Point:
location: {
type: "Point",
coordinates: [-73.856077, 40.848447]
}
For a list of the GeoJSON objects supported in MongoDB as well as examples, see GeoJSON objects.
MongoDB geospatial queries on GeoJSON objects calculate on a sphere; MongoDB uses the WGS84 reference system for geospatial queries on GeoJSON objects.
Legacy Coordinate Pairs¶
To calculate distances on a Euclidean plane, store your location data as legacy coordinate pairs and use a 2d index. MongoDB supports spherical surface calculations on legacy coordinate pairs via a 2dsphere index by converting the data to the GeoJSON Point type.
To specify data as legacy coordinate pairs, you can use either an array (preferred) or an embedded document.
- Specify via an array (Preferred):
<field>: [ <x>, <y> ]
If specifying latitude and longitude coordinates, list the longitude first and then latitude; i.e.
<field>: [<longitude>, <latitude> ]
If specifying latitude and longitude coordinates, list the longitude first and then latitude:
- Valid longitude values are between
-180
and180
, both inclusive. - Valid latitude values are between
-90
and90
(both inclusive).
- Valid longitude values are between
- Specify via an embedded document:
<field>: { <field1>: <x>, <field2>: <y> }
If specifying latitude and longitude coordinates, the first field, regardless of the field name, must contains the longitude value and the second field, the latitude value ; i.e.
<field>: { <field1>: <longitude>, <field2>: <latitude> }
- Valid longitude values are between
-180
and180
, both inclusive. - Valid latitude values are between
-90
and90
(both inclusive).
- Valid longitude values are between
To specify legacy coordinate pairs, arrays are preferred over an embedded document as some languages do not guarantee associative map ordering.
Geospatial Indexes¶
MongoDB provides the following geospatial index types to support the geospatial queries.
2dsphere
¶
2dsphere indexes support queries that calculate geometries on an earth-like sphere.
To create a 2dsphere
index, use the
db.collection.createIndex()
method and specify the string
literal "2dsphere"
as the index type:
db.collection.createIndex( { <location field> : "2dsphere" } )
where the <location field>
is a field whose value is either a
GeoJSON object or a legacy
coordinates pair.
For more information on the 2dsphere
index, see
2dsphere Indexes.
2d
¶
2d indexes support queries that calculate
geometries on a two-dimensional plane.
Although the index can support $nearSphere
queries that
calculate on a sphere, if possible, use the 2dsphere index
for spherical queries.
To create a 2d
index, use the db.collection.createIndex()
method, specifying the location field as the key and the string literal
"2d"
as the index type:
db.collection.createIndex( { <location field> : "2d" } )
where the <location field>
is a field whose value is a legacy
coordinates pair.
For more information on the 2d
index, see 2d Indexes.
Geospatial Indexes and Sharded Collections¶
You cannot use a geospatial index as a shard key when sharding a collection. However, you can create a geospatial index on a sharded collection by using a different field as the shard key.
For sharded collections, queries using $near
and $nearSphere
are not
supported. You can instead use either the geoNear
command
or the $geoNear
aggregation stage.
You can also query for geospatial data for a sharded cluster using
$geoWithin
and $geoIntersect
.
Covered Queries¶
A geospatial indexes cannot cover a query.
Geospatial Queries¶
Note
For spherical queries, use the 2dsphere
index result.
The use of 2d
index for spherical queries may lead to incorrect
results, such as the use of the 2d
index for spherical queries
that wrap around the poles.
Geospatial Query Operators¶
MongoDB provides the following geospatial query operators:
Name | Description |
---|---|
$geoIntersects |
Selects geometries that intersect with a GeoJSON geometry.
The 2dsphere index supports
$geoIntersects . |
$geoWithin |
Selects geometries within a bounding GeoJSON geometry. The 2dsphere and 2d indexes support
$geoWithin . |
$near |
Returns geospatial objects in proximity to a point.
Requires a geospatial index. The 2dsphere and 2d indexes support
$near . |
$nearSphere |
Returns geospatial objects in proximity to a point on a sphere.
Requires a geospatial index. The 2dsphere and 2d indexes support
$nearSphere . |
For more details, including examples, see the individual reference page.
Geospatial Command¶
MongoDB provides the following geospatial command:
Command | Description |
---|---|
geoNear |
Performs a geospatial query that returns the documents closest to a given point.
|
For more details, including examples, see geoNear
reference page.
Geospatial Aggregation Stage¶
MongoDB provides the following geospatial aggregation pipeline stage:
Stage | Description |
---|---|
$geoNear |
Returns an ordered stream of documents based on the proximity to a
geospatial point. Incorporates the functionality of
|
For more details, including examples, see $geoNear
reference page.
Geospatial Models¶
MongoDB geospatial queries can interpret geometry on a flat surface or a sphere.
2dsphere
indexes support only spherical queries (i.e. queries that
interpret geometries on a spherical surface).
2d
indexes support flat queries (i.e. queries that interpret
geometries on a flat surface) and some spherical queries. While 2d
indexes support some spherical queries, the use of 2d
indexes for
these spherical queries can result in error. If possible, use
2dsphere
indexes for spherical queries.
The following table lists the geospatial query operators, supported query, used by each geospatial operations:
Operation | Spherical/Flat Query | Notes |
---|---|---|
$near (GeoJSON centroid
point in this line and the following line, 2dsphere index) |
Spherical | See also the $nearSphere operator, which provides the
same functionality when used with GeoJSON and a 2dsphere index. |
$near (legacy coordinates, 2d index) |
Flat | |
$nearSphere (GeoJSON point, 2dsphere index) |
Spherical | Provides the same functionality as For spherical queries, it may be preferable to use
|
$nearSphere (legacy coordinates, 2d index) |
Spherical | Use GeoJSON points instead. |
$geoWithin : { $geometry : … } |
Spherical | |
$geoWithin : { $box : … } |
Flat | |
$geoWithin : { $polygon : … } |
Flat | |
$geoWithin : { $center : … } |
Flat | |
$geoWithin : { $centerSphere : … } |
Spherical | |
$geoIntersects |
Spherical | |
geoNear (2dsphere index) |
Spherical | |
geoNear (2d index) |
Flat | |
$geoNear (2dsphere index) |
Spherical | |
$geoNear (2d index) |
Flat |
Example¶
Create a collection places
with the following documents:
db.places.insert( {
name: "Central Park",
location: { type: "Point", coordinates: [ -73.97, 40.77 ] },
category: "Parks"
} );
db.places.insert( {
name: "Sara D. Roosevelt Park",
location: { type: "Point", coordinates: [ -73.9928, 40.7193 ] },
category: "Parks"
} );
db.places.insert( {
name: "Polo Grounds",
location: { type: "Point", coordinates: [ -73.9375, 40.8303 ] },
category: "Stadiums"
} );
The following operation creates a 2dsphere
index on the
location
field:
db.places.createIndex( { location: "2dsphere" } )
The following query uses the $near
operator to return
documents that are at least 1000 meters from and at most 5000 meters
from the specified GeoJSON point, sorted in order from nearest to
farthest:
db.places.find(
{
location:
{ $near:
{
$geometry: { type: "Point", coordinates: [ -73.9667, 40.78 ] },
$minDistance: 1000,
$maxDistance: 5000
}
}
}
)
The following operation uses the geoNear
command to return
documents that match the query filter { category: "Parks" }
, sorted
in order of nearest to farthest to the specified GeoJSON point:
db.runCommand(
{
geoNear: "places",
near: { type: "Point", coordinates: [ -73.9667, 40.78 ] },
spherical: true,
query: { category: "Parks" }
}
)