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
typethat specifies the GeoJSON object type, anda field named
coordinatesthat specifies the object's coordinates.
<field>: { type: <GeoJSON type> , coordinates: <coordinates> }
Important
If specifying latitude and longitude coordinates, list the longitude first, and then latitude.
Valid longitude values are between
-180and180, both inclusive.Valid latitude values are between
-90and90, both inclusive.
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
Use legacy coordinate pairs for flat (Euclidean) calculations with a
2d Indexes index. To perform spherical calculations, convert legacy
pairs to a GeoJSON Point and use a 2dsphere Indexes index.
To specify data as legacy coordinate pairs, you can use either an array (preferred) or an embedded document.
- Array:
<field>: [ <x>, <y> ] When you use longitude and latitude, list longitude first, then latitude:
<field>: [ <longitude>, <latitude> ] Valid longitude values are between
-180and180, both inclusive.Valid latitude values are between
-90and90, both inclusive.
- Embedded document:
<field>: { <field1>: <x>, <field2>: <y> } If you use longitude and latitude, the first field must be longitude and the second must be latitude:
<field>: { <field1>: <longitude>, <field2>: <latitude> } Valid longitude values are between
-180and180, both inclusive.Valid latitude values are between
-90and90, both inclusive.
Use arrays for legacy coordinate pairs because some languages do not preserve object field ordering.
Geospatial Indexes
Geospatial indexes support queries on data stored as GeoJSON objects or legacy coordinate pairs. You can use geospatial indexes to improve performance for queries on geospatial data or to run certain geospatial queries.
MongoDB provides two types of geospatial indexes:
2dsphere Indexes, which support queries that interpret geometry on a sphere.
2d Indexes, which support queries that interpret geometry on a flat surface.
For more information on geospatial indexes, see Geospatial Indexes.
Geospatial Queries
Note
Using a 2d index for queries on spherical data
can return incorrect results or an error. For example,
2d indexes don't support spherical queries that wrap
around the poles.
Geospatial Query Operators
MongoDB provides the following geospatial query operators. For more details, including examples, see the respective reference pages.
Name | Description |
|---|---|
Selects geometries that intersect with a GeoJSON geometry.
The 2dsphere index supports
| |
Selects geometries within a bounding GeoJSON geometry. The 2dsphere and 2d indexes support
| |
Returns geospatial objects in proximity to a point.
Requires a geospatial index. The | |
Returns geospatial objects in proximity to a point on a sphere.
Requires a geospatial index. The |
Note
Time series collections only support the $geoNear
aggregation stage for sorting geospatial data from queries against 2dsphere indexes. You can't use $near and
$nearSphere operators on time series collections.
Geospatial Aggregation Stage
MongoDB provides the following geospatial aggregation pipeline stage:
Stage | Description |
|---|---|
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 |
|---|---|---|
Spherical | See also the | |
| Flat | |
| Spherical | Provides the same functionality as For spherical queries, it may be preferable to use
|
| Spherical | Use GeoJSON points instead. |
| Spherical | |
| Flat | |
| Flat | |
| Flat | |
| Spherical | |
Spherical | ||
Spherical | ||
Flat |
Perform Geospatial Queries in Atlas
Examples
Create a collection places with the following documents:
db.places.insertMany( [ { name: "Central Park", location: { type: "Point", coordinates: [ -73.97, 40.77 ] }, category: "Parks" }, { name: "Sara D. Roosevelt Park", location: { type: "Point", coordinates: [ -73.9928, 40.7193 ] }, category: "Parks" }, { 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 places collection above has a 2dsphere index.
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 aggregation
operation to return documents that match the query filter { category:
"Parks" }, sorted in order of nearest to farthest to the specified
GeoJSON point:
db.places.aggregate( [ { $geoNear: { near: { type: "Point", coordinates: [ -73.9667, 40.78 ] }, spherical: true, query: { category: "Parks" }, distanceField: "calcDistance" } } ] )