$geoNear is a MongoDB aggregation stage that finds documents nearest to a point and returns them sorted by distance—ideal for store locators and “places near me” features.
Remember
$geoNear = "closest places to this point"
{
$geoNear: {
near: { type: "Point", coordinates: [lng, lat] },
distanceField: "distanceMeters",
spherical: true
}
}
MUST be the first stage
needs a 2dsphere (or 2d) index
GeoJSON order: [longitude, latitude]
spherical: true → distance in meters
maxDistance → search radius
Cannot use inside $facet
Start the pipeline with $geoNear (near + distanceField).
Optionally set maxDistance / query, then $limit or $project.
Option
Required?
Role
near
Yes
Center point (GeoJSON Point)
distanceField
Yes
Output field name for distance
spherical
No
true for Earth-like meters with 2dsphere
maxDistance
No
Radius cap (meters when spherical + GeoJSON)
query
No
Extra filter (e.g. category)
Pseudocode
Pseudocode
assert: $geoNear is stage 1
assert: geospatial index exists on location field
for each document:
d = distance(near, document.location) // meters if spherical
if maxDistance set and d > maxDistance → skip
if query fails → skip
document[distanceField] = d
emit documents sorted by d ascending
(nearest first)
Reference
Cheat Sheet
Keep these facts handy while building location search.
Topic
Detail
Type
Aggregation stage (geospatial)
Position
Must be first in the pipeline
Index
2dsphere (GeoJSON) or legacy 2d
Coordinates
[longitude, latitude]
Sort order
Nearest → farthest (built-in)
Units
Meters with GeoJSON + spherical: true
Not allowed
Inside $facet; after other stages
Try it
Live Preview
Approximate nearest places from a sample point (teaching model—distances are rounded estimates).
Center: [-73.9857, 40.7484] (near Empire State Building).
Result
Times Square Cafe ~1200 m
Midtown Library ~1500 m
Hudson Yards Park ~1800 m
Central Park ~2400 m
Brooklyn Bridge View ~5200 m
Trace
Worked Walkthrough — Nearest First
User stands near Empire State Building [-73.9857, 40.7484]. Goal: list places closest first.
Calculation
1. Index: { location: "2dsphere" }
2. $geoNear first:
near = Point [-73.9857, 40.7484]
distanceField = "distanceMeters"
spherical = true
3. MongoDB computes distance for each place
4. Emits ascending order (no extra $sort)
Typical order (approx):
Times Square Cafe → closest
Midtown Library
…
Brooklyn Bridge View → farther
Code
MongoDB Examples
We use a small places collection with GeoJSON Points. Create the 2dsphere index once, then run nearest and radius searches in mongosh.
Example 1 — Sample Data
Five New York landmarks as GeoJSON Points, plus the required 2dsphere index.
Nothing can run before $geoNear. Put filters in query or stages after it.
coords
Longitude comes first
GeoJSON is [lng, lat]. Swapping them places your pin in the wrong ocean.
index
No geospatial index → error
Create 2dsphere on the location field before running the pipeline.
facet
Not allowed inside $facet
$facet sub-pipelines cannot include $geoNear. Run proximity search as its own pipeline.
Analysis
Performance Notes
Approach
Cost
Best for
$geoNear + maxDistance
Index + radius
Delivery / store radius
$geoNear + $limit
Stops after N nearest
Map pin lists
No maxDistance on huge sets
Many distance calcs
Avoid when possible
Keep a 2dsphere index healthy, prefer a radius when the UI has one, and $limit early for “top N nearby” screens.
Remember
Key Takeaways
Role: nearest documents, sorted by distance.
Rules: first stage + geospatial index required.
Coords:[longitude, latitude] for GeoJSON.
Radius:maxDistance in meters when spherical.
One line:$geoNear answers “what is closest to this point?”
Frequently Asked Questions
$geoNear returns documents sorted from nearest to farthest relative to a point (near). Each result can include a calculated distance in the field you name with distanceField—ideal for store locators and “near me” search.
It must be the first stage. You can add $match, $limit, or $project after it, but nothing may come before $geoNear.
A geospatial index—usually 2dsphere for GeoJSON. Without one, $geoNear fails. Create with db.collection.createIndex({ location: "2dsphere" }).
GeoJSON uses [longitude, latitude]—not lat/long the way many maps display. Example: near Empire State Building ≈ [-73.9857, 40.7484]. The near value should be type: "Point".
With GeoJSON and spherical: true, distances are in meters. maxDistance caps how far matches can be; minDistance excludes places closer than the threshold (a donut-shaped search).
No. $geoNear cannot appear inside $facet sub-pipelines and cannot follow another stage—always start the pipeline with $geoNear when you need proximity sorting.