0
0
MongodbHow-ToBeginner · 3 min read

How to Use $geoNear in Aggregation in MongoDB

Use the $geoNear stage as the first step in a MongoDB aggregation pipeline to find documents near a specified point. It requires a near field with coordinates and a distanceField to store calculated distances. This stage sorts documents by proximity and can filter by max distance or spherical geometry.
📐

Syntax

The $geoNear stage must be the first stage in an aggregation pipeline. It requires these main fields:

  • near: The point to search near, given as GeoJSON coordinates.
  • distanceField: The field name to add the calculated distance to each document.
  • spherical: Boolean to specify if calculations use spherical geometry (true for Earth).
  • maxDistance (optional): Limits results to documents within this distance (in meters).
  • query (optional): Filters documents before calculating distances.
json
{
  $geoNear: {
    near: { type: "Point", coordinates: [ <longitude>, <latitude> ] },
    distanceField: "distance",
    spherical: true,
    maxDistance: <maxDistanceInMeters>,
    query: { <filter> }
  }
}
💻

Example

This example finds places near a given point, adds the distance in meters, and limits results to 5000 meters.

javascript
db.places.aggregate([
  {
    $geoNear: {
      near: { type: "Point", coordinates: [ -73.99279, 40.719296 ] },
      distanceField: "distance",
      spherical: true,
      maxDistance: 5000
    }
  }
])
Output
[ { _id: ObjectId("..."), name: "Coffee Shop", location: { type: "Point", coordinates: [ -73.991, 40.720 ] }, distance: 123.45 }, { _id: ObjectId("..."), name: "Bookstore", location: { type: "Point", coordinates: [ -73.993, 40.718 ] }, distance: 234.56 } ]
⚠️

Common Pitfalls

  • Not using $geoNear as the first stage: It must be the first stage in the pipeline.
  • Missing near or distanceField: These are required fields.
  • Coordinates order: Coordinates must be in [longitude, latitude] order.
  • Index requirement: The collection must have a 2dsphere index on the location field.
  • Forgetting spherical: true: Use spherical true for Earth-like calculations.
javascript
/* Wrong: $geoNear not first stage */
db.places.aggregate([
  { $match: { category: "coffee" } },
  { $geoNear: { near: { type: "Point", coordinates: [ -73.99279, 40.719296 ] }, distanceField: "dist", spherical: true } }
])

/* Right: $geoNear first stage */
db.places.aggregate([
  { $geoNear: { near: { type: "Point", coordinates: [ -73.99279, 40.719296 ] }, distanceField: "dist", spherical: true, query: { category: "coffee" } } }
])
📊

Quick Reference

FieldDescriptionRequiredExample
nearGeoJSON point to search nearYes{ type: "Point", coordinates: [ -73.99279, 40.719296 ] }
distanceFieldField to store distanceYes"distance"
sphericalUse spherical geometryYestrue
maxDistanceMax distance in metersNo5000
queryFilter documents before distance calcNo{ category: "coffee" }

Key Takeaways

Always use $geoNear as the first stage in your aggregation pipeline.
Specify the 'near' point with GeoJSON coordinates in [longitude, latitude] order.
Include 'distanceField' to get the distance calculated for each document.
Ensure your collection has a 2dsphere index on the location field.
Use 'spherical: true' for accurate Earth distance calculations.