A delivery application may need the closest open pickup locations to a customer. Sorting longitude values does not answer that question: geographic distance depends on both coordinates and the spherical model. MongoDB supports GeoJSON geometry and geospatial operators for these tasks. This reference uses MongoDB 8.0 with ordinary collections, GeoJSON Points, and a 2dsphere index. The controlled fixtures place points near the equator so their nearby and containment results are easy to reason about. They demonstrate database geometry, not road travel times. A route planner or delivery promise needs additional information such as roads, traffic, and service constraints.
Validate longitude-first GeoJSON input
A Point has a type value of Point and a coordinates array. For geographic GeoJSON, the coordinate order is longitude followed by latitude. Longitude ranges from minus one hundred eighty to one hundred eighty degrees; latitude ranges from minus ninety to ninety. A form often asks latitude first, so explicitly map its named inputs instead of passing an unlabeled pair through the system.
A swapped pair can remain numerically valid and place the point in an entirely different region. Checking only numeric bounds would not catch every such mistake. Validate the expected service region and use unambiguous field labels at boundaries. The main fixture uses [0, 0], [0.01, 0], and [1, 0]; all are longitude-first positions on the equator. GeoJSON is not the same representation as legacy planar coordinate pairs. Choose a documented spherical GeoJSON model and a 2dsphere index when the application concerns positions on Earth.
Match the index and operator to the question
Create a 2dsphere index on the geometry field. A $near query with a GeoJSON Point requires a suitable geospatial index and returns results ordered by distance. Its minimum and maximum distances use meters for the GeoJSON form. In the main fixture a two-thousand-meter radius includes the origin and a point about one kilometer east, while a point roughly one degree east is much farther away.
Do not apply a separate name sort and still describe the output as closest-first. That changes the result ordering. If the product needs a different display order, make that choice explicit after applying the spatial eligibility rule. A geometry containment query asks a different question from proximity: being inside a service polygon does not imply a particular nearest-first order. Combining unrelated special indexes such as a text search requirement and a near query can have documented limitations; design the query from supported operator combinations rather than assuming all index types can be used together.
Use geoNear for computed-distance pipelines
The $geoNear aggregation stage can expose a computed distance field while applying its spatial query. It must be the first stage under the documented pipeline rules. Specify the indexed geometry key when the collection has multiple relevant geospatial indexes, and include ordinary eligibility conditions in its query option. Subsequent stages can project, limit, or combine the distance with report fields.
The practice asks for the nearest open locations and limits its result after the spatial stage. A closed location at the origin would otherwise appear closer than an open location farther away; putting open: true in the geoNear query excludes it before ranking. A later match after a small limit could incorrectly discard closed candidates without recovering farther open candidates. Exact computed distances depend on the documented model and engine details, so this fixture prints stable selected IDs and a nonnegative-distance assertion rather than presenting a rounded distance as a driving distance.
Distinguish containment, intersection, and routing
A $geoWithin predicate checks whether a stored geometry is within a supplied geometry. The main polygon is a small closed ring whose first and last coordinates match. Its interior contains the first two fixture points; the point at longitude one is outside. The fixture adds an explicit _id sort because containment does not supply the near operator's distance ordering.
$geoIntersects instead asks whether geometries intersect. Boundary behavior, large polygons, winding, and special coordinate reference system rules deserve separate care for real geographic datasets. Do not approximate a continent-sized polygon by extending this small square without reviewing those rules. Spatial proximity also ignores obstacles and street networks. A warehouse across a river might be close by spherical distance yet slow to reach. Treat a nearby query as an eligibility or candidate-selection step and incorporate business constraints separately. Missing or invalid geometry needs an explicit ingestion and reporting policy rather than silently becoming a usable location.
MongoDB documentation and version notes
MongoDB Geospatial Queries Examples
Each example shows the code, the output it produces and what each part does.
Comparing $near and $geoWithin results
The complete mongosh fixture resets a dedicated places collection, builds the required geospatial index, and inserts three named positions. The nearby query returns IDs one and two in distance order. A small polygon independently selects the same two IDs; an explicit sort stabilizes its printed result. Matching IDs here does not make the two predicates interchangeable. The selected radius and polygon merely happen to include the same controlled points. Moving the second point north or changing the polygon can separate the results without changing either operator's meaning.
const places = db.getSiblingDB('codevra_ref_geo').getCollection('places');
places.drop();
places.createIndex({ location: '2dsphere' });
places.insertMany([
{ _id: 1, name: 'Origin', location: { type: 'Point', coordinates: [0, 0] } },
{ _id: 2, name: 'East', location: { type: 'Point', coordinates: [0.01, 0] } },
{ _id: 3, name: 'Far', location: { type: 'Point', coordinates: [1, 0] } }
]);
const near = places.find({ location: { $near: { $geometry: { type: 'Point', coordinates: [0, 0] }, $maxDistance: 2000 } } }).toArray();
print('near: ' + near.map(p => p._id).join(','));
const polygon = { type: 'Polygon', coordinates: [[[-0.02, -0.02], [0.02, -0.02], [0.02, 0.02], [-0.02, 0.02], [-0.02, -0.02]]] };
const within = places.find({ location: { $geoWithin: { $geometry: polygon } } }).sort({ _id: 1 }).toArray();
print('within: ' + within.map(p => p._id).join(','));near: 1,2
within: 1,2MongoDB Geospatial Queries in Real Projects
Find the nearest open pickup points with $geoNear
Find the two nearest open pickup locations while excluding a closed point at the origin. The solution creates a fresh collection and puts the ordinary open predicate inside geoNear. The distance field is available for subsequent application logic; the printed result verifies its nonnegative value without assigning it road-distance meaning. The first-stage placement and pre-limit eligibility filter are central to the exercise. The two open positions have different distances, so their relative order is unambiguous. If a product needs deterministic ordering among equal distances, define and implement its tie policy explicitly.
const places = db.getSiblingDB('codevra_ref_geo').getCollection('practice');
places.drop(); places.createIndex({ location: '2dsphere' });
places.insertMany([
{ _id: 1, open: false, location: { type: 'Point', coordinates: [0, 0] } },
{ _id: 2, open: true, location: { type: 'Point', coordinates: [0.01, 0] } },
{ _id: 3, open: true, location: { type: 'Point', coordinates: [0.02, 0] } }
]);
const result = places.aggregate([
{ $geoNear: { near: { type: 'Point', coordinates: [0, 0] }, key: 'location', distanceField: 'meters', spherical: true, query: { open: true } } },
{ $limit: 2 },
{ $project: { _id: 1, meters: 1 } }
]).toArray();
print('open: ' + result.map(p => p._id).join(','));
print('nonnegative distances: ' + result.every(p => p.meters >= 0));open: 2,3
nonnegative distances: trueMongoDB Geospatial Queries FAQ
Why does coordinate order matter even with valid numbers?
Both coordinates may fit their allowed ranges when swapped. The resulting Point is then legal but represents a different location. Map named longitude and latitude inputs deliberately and validate the intended service region. A legal numeric pair is weaker evidence than a semantically correct location. A geospatial index cannot infer which order the user meant.
Does maxDistance use degrees in this example?
No. The GeoJSON Point form used with the spherical index expresses these distance limits in meters. Legacy coordinate forms have different documented unit rules. Keep representation, index model, and units together when reading an example; copying a numeric limit without that context can produce a drastically different geographic radius. Label the radius in meters in application inputs and logs so unit mistakes remain visible.
Can I put match before geoNear?
The documented stage must be first in its aggregation context. Include ordinary eligibility conditions in the stage's query option when applicable, then use later pipeline stages for subsequent processing. Filtering only after a small limit can miss eligible locations that were farther away than excluded candidates. Stage placement therefore affects both validity and result completeness.
Is the nearest location always the fastest delivery?
No. The query ranks geometric proximity under its model, not road routes or travel time. Traffic, water crossings, opening hours, inventory, and delivery capacity can change the operational choice. Use the spatial result as one input to the application's decision and explain which notion of distance is presented to the user.
MongoDB Geospatial Queries Exercises
Answer each one and check it instantly. If you get stuck, open the hint before the answer.
Why does the practice return IDs 2 and 3 instead of closed ID 1?
MongoDB Geospatial Queries Quiz
2 questions to check what you learned.
Which GeoJSON Point order is correct for longitude 12 and latitude 34?
- coordinates: [12, 34]
- coordinates: [34, 12]
- coordinates: [12, 34, "meters"]
What ordering does geoWithin guarantee for the matched fixture?
- No nearest-first ordering; the fixture sorts by _id explicitly
- The same distance order as $near for every polygon
- Alphabetical order by each place name