Working with Geospatial Queries
1. Storing GeoJSON Objects
| Type | Example |
|---|---|
| Point | {type:"Point", coordinates:[lng, lat]} |
| Polygon | {type:"Polygon", coordinates:[[[lng,lat],...]]} |
| Index | 2dsphere on the field |
2. Storing Legacy Coordinates
| Form | Index |
|---|---|
| [lng, lat] | 2d or 2dsphere |
| {lng, lat} | Field-order embed (legacy 2d) |
3. Using $near for Proximity Queries
| Field | Effect |
|---|---|
| $geometry | GeoJSON Point |
| $maxDistance | Meters (2dsphere) |
| $minDistance | Meters |
| Result | Sorted nearest-first |
db.places.find({ location: { $near: { $geometry: { type: "Point", coordinates: [-73.97, 40.77] }, $maxDistance: 1000 } } });
4. Using $nearSphere for Spherical Distance
| Aspect | Detail |
|---|---|
| Form | Same as $near but always spherical |
| 2d index | Distances in radians; 2dsphere = meters |
5. Using $geoWithin for Boundary Queries
| Form | Effect |
|---|---|
| $geometry: Polygon | Inside polygon |
| $centerSphere: [[lng,lat], radians] | Circle on sphere |
| $box, $polygon, $center | Legacy flat shapes |
| Result order | Not sorted |
6. Using $geoIntersects for Intersection
| Aspect | Detail |
|---|---|
| Form | {$geoIntersects: {$geometry: ...}} |
| Use | Match geometries crossing input |
| Requires | 2dsphere index |
7. Using $centerSphere for Circular Regions
| Field | Description |
|---|---|
| Center | [lng, lat] |
| Radius | Radians (divide meters by 6378100) |
8. Using $box for Rectangular Regions
| Form | Effect |
|---|---|
$geoWithin: {$box: [[lng1,lat1],[lng2,lat2]]} | Flat bounding box (2d only) |
9. Using $polygon for Custom Shapes
| Form | Effect |
|---|---|
$geoWithin: {$polygon: [[lng,lat], ...]} | Flat polygon (2d) |
| Modern | Use GeoJSON Polygon with 2dsphere |
10. Calculating Distances
| Stage | Detail |
|---|---|
| $geoNear (aggregation) | Returns docs with computed distanceField |
| distanceMultiplier | Convert meters to other units |
| includeLocs | Add matched location field |
| key | Specify geo field when multiple exist |
db.places.aggregate([
{ $geoNear: { near: { type: "Point", coordinates: [-73.97, 40.77] }, distanceField: "dist", maxDistance: 5000, spherical: true } }
]);
11. Understanding Geospatial Query Limitations
| Limit | Detail |
|---|---|
| $near + sharded | Use $geoNear stage instead |
| $near returns sorted | Can't combine with $sort easily |
| Antipodal polygons | Split into smaller pieces |