MongoDB Geospatial
Parent: MongoDB Expert Knowledge · Published reference · snapshot 2026-09-08 · skill mongodb-expert/references/mongodb-geospatial.md
↓ Facts as markdownall context files
Use when designing or troubleshooting MongoDB geospatial queries, indexes, or data models. Covers GeoJSON storage, 2dsphere and 2d index types, proximity and containment operators ($near, $geoWithin,
These notes link each claim to its source. Some citations identify archived research reports that are no longer hosted on this site. A published reference means the content is available; it does not certify independent review or accuracy.Read the editorial policy and follow the sources before relying on a claim.
Description
- Use when designing or troubleshooting MongoDB geospatial queries, indexes, or data models. Covers GeoJSON storage, 2dsphere and 2d index types, proximity and containment operators ($near, $geoWithin, $geoNear, $geoIntersects), radius calculations, $lookup pipeline joins across spatial collections, and common anti-patterns. Apply this skill whenever a schema includes location fields, a query filters by distance or bounding region, or a $geoNear aggregation stage needs tuning. [archived source: https://llms-explorer.com/sources/mdb-context-hub/mongodb-geospatial/#description]
1. GeoJSON Object Types
- MongoDB natively stores and queries the GeoJSON spec. Every GeoJSON field is an embedded document with a type string and a coordinates array. Longitude always comes before latitude - the opposite of most mapping UIs. [archived source: https://llms-explorer.com/sources/mdb-context-hub/mongodb-geospatial/#1-geojson-object-types]
- Insert a document with a GeoJSON Point field: [archived source: https://llms-explorer.com/sources/mdb-context-hub/mongodb-geospatial/#1-geojson-object-types]
2. 2dsphere Indexes
- A 2dsphere index supports queries on GeoJSON geometry computed over a sphere modelled on WGS84 (the same datum used by GPS). Version 3 has been the default since MongoDB 3.2; MongoDB 8.3+ defaults to version 4. It handles Points, LineStrings, and Polygons stored as GeoJSON and supports all geospatial query operators. [archived source: https://llms-explorer.com/sources/mdb-context-hub/mongodb-geospatial/#2-2dsphere-indexes]
- Handles wraparound at the anti-meridian (180° longitude) correctly. [archived source: https://llms-explorer.com/sources/mdb-context-hub/mongodb-geospatial/#2-2dsphere-indexes]
- Required by $geoNear, $near, $nearSphere, $geoWithin with $centerSphere. [archived source: https://llms-explorer.com/sources/mdb-context-hub/mongodb-geospatial/#2-2dsphere-indexes]
- 2dsphere indexes are always sparse (MongoDB ignores the sparse option). A document missing the geo field - or where it is null or an empty array - is not indexed, whether the index is standalone or compound. In a compound 2dsphere index, only the geo field determines whether a document is indexed. [archived source: https://llms-explorer.com/sources/mdb-context-hub/mongodb-geospatial/#2-2dsphere-indexes]
3. 2d Indexes
- A 2d index uses planar (flat-earth) geometry. It is a legacy index type intended for coordinate pairs stored as [lng, lat] arrays (not GeoJSON documents). Use it only when the coordinate space is genuinely flat (e.g., game maps, CAD drawings, grid systems) and spherical correction is not needed. [archived source: https://llms-explorer.com/sources/mdb-context-hub/mongodb-geospatial/#3-2d-indexes]
- Limitations vs. 2dsphere: [archived source: https://llms-explorer.com/sources/mdb-context-hub/mongodb-geospatial/#3-2d-indexes]
- No polygon-edge wraparound. [archived source: https://llms-explorer.com/sources/mdb-context-hub/mongodb-geospatial/#3-2d-indexes]
- Distance unit is degrees, not metres. [archived source: https://llms-explorer.com/sources/mdb-context-hub/mongodb-geospatial/#3-2d-indexes]
- Does not support GeoJSON input documents. [archived source: https://llms-explorer.com/sources/mdb-context-hub/mongodb-geospatial/#3-2d-indexes]
- Cannot use $geoNear aggregation with spherical: true. [archived source: https://llms-explorer.com/sources/mdb-context-hub/mongodb-geospatial/#3-2d-indexes]
4. $geoNear Aggregation Stage
- $geoNear must be the first stage of an aggregation pipeline. It returns documents sorted by computed distance from a reference point and appends the distance value to each document under distanceField. A geospatial index is required; if multiple exist, specify key. [archived source: https://llms-explorer.com/sources/mdb-context-hub/mongodb-geospatial/#4-geonear-aggregation-stage]
- distanceMultiplier converts metres to another unit: [archived source: https://llms-explorer.com/sources/mdb-context-hub/mongodb-geospatial/#4-geonear-aggregation-stage]
- includeLocs records the matched location field alongside distance: [archived source: https://llms-explorer.com/sources/mdb-context-hub/mongodb-geospatial/#4-geonear-aggregation-stage]
5. $geoWithin
- $geoWithin finds documents whose geometry is entirely contained within a specified shape. It does not sort results and does not require a geospatial index (though an index improves performance significantly on large collections). [archived source: https://llms-explorer.com/sources/mdb-context-hub/mongodb-geospatial/#5-geowithin]
6. $geoIntersects
- $geoIntersects finds documents whose GeoJSON geometry intersects - shares any point with - the query geometry. Useful for routes, delivery zones, and region overlap checks. Requires a 2dsphere index for good performance. [archived source: https://llms-explorer.com/sources/mdb-context-hub/mongodb-geospatial/#6-geointersects]
7. $near and $nearSphere
- $near and $nearSphere are query operators (not aggregation stages). Both sort results by distance and require a geospatial index. They cannot be used inside $or or $and alongside other $near/$nearSphere expressions. [archived source: https://llms-explorer.com/sources/mdb-context-hub/mongodb-geospatial/#7-near-and-nearsphere]
- $near vs. $geoNear: Use $near for a simple .find() that returns sorted documents. Use $geoNear when you need the distance value in the result, further pipeline stages, or more control (distanceMultiplier, query pre-filter, key selection). [archived source: https://llms-explorer.com/sources/mdb-context-hub/mongodb-geospatial/#7-near-and-nearsphere]
8. Radius Queries
- Converting a real-world radius to the unit each operator expects: [archived source: https://llms-explorer.com/sources/mdb-context-hub/mongodb-geospatial/#8-radius-queries]
9. Geospatial $lookup Patterns
- Geospatial query operators ($geoIntersects, $geoWithin, $near) are query operators, not aggregation expression operators - they cannot be used inside $expr. Inside a $lookup pipeline stage, place them directly inside $match against a field in the joined collection. The outer document's location must be supplied via $geoNear output or by denormalizing the coordinate. [archived source: https://llms-explorer.com/sources/mdb-context-hub/mongodb-geospatial/#9-geospatial-lookup-patterns]
- Performance considerations for geospatial $lookup: [archived source: https://llms-explorer.com/sources/mdb-context-hub/mongodb-geospatial/#9-geospatial-lookup-patterns]
- $geoIntersects / $geoWithin inside a $lookup pipeline runs once per driving document; ensure a 2dsphere index on the joined collection's geometry field. [archived source: https://llms-explorer.com/sources/mdb-context-hub/mongodb-geospatial/#9-geospatial-lookup-patterns]
- Add a $match with a bounding-box $geoWithin before $lookup to narrow candidates when the joined collection is large. [archived source: https://llms-explorer.com/sources/mdb-context-hub/mongodb-geospatial/#9-geospatial-lookup-patterns]
- Denormalizing the zone or region ID at write time (Recommended pattern above) eliminates the per-row geo scan entirely and scales best. [archived source: https://llms-explorer.com/sources/mdb-context-hub/mongodb-geospatial/#9-geospatial-lookup-patterns]
- For hot-path proximity queries at scale, consider Atlas Search $search with a geoWithin or geoShape filter, which uses a dedicated search index and avoids aggregation pipeline overhead. [archived source: https://llms-explorer.com/sources/mdb-context-hub/mongodb-geospatial/#9-geospatial-lookup-patterns]
References
- MongoDB Geospatial Queries overview: https://www.mongodb.com/docs/manual/geospatial-queries/ [archived source: https://llms-explorer.com/sources/mdb-context-hub/mongodb-geospatial/#references]
- Geospatial query operator reference: https://www.mongodb.com/docs/manual/reference/operator/query-geospatial/ [archived source: https://llms-explorer.com/sources/mdb-context-hub/mongodb-geospatial/#references]
- 2dsphere index documentation: https://www.mongodb.com/docs/manual/core/2dsphere/ [archived source: https://llms-explorer.com/sources/mdb-context-hub/mongodb-geospatial/#references]
- $geoNear aggregation stage: https://www.mongodb.com/docs/manual/reference/operator/aggregation/geoNear/ [archived source: https://llms-explorer.com/sources/mdb-context-hub/mongodb-geospatial/#references]
- GeoJSON objects reference: https://www.mongodb.com/docs/manual/reference/geojson/ [archived source: https://llms-explorer.com/sources/mdb-context-hub/mongodb-geospatial/#references]
- Geospatial tutorial (find restaurants): https://www.mongodb.com/docs/manual/tutorial/geospatial-tutorial/ [archived source: https://llms-explorer.com/sources/mdb-context-hub/mongodb-geospatial/#references]
Where this helps
- Storing and querying location data for a delivery, ride-share, store-locator, or asset-tracking application where MongoDB is already the primary datastore. [source] — AI-suggested, synthesized from this pack's existing facts — not extracted from a source document.
- Building proximity search ("nearest N points") or containment checks ("is this point inside this zone") without standing up a separate GIS-specific database. [source] — AI-suggested, synthesized from this pack's existing facts — not extracted from a source document.
- Joining geospatial data across collections — for example, matching a delivery address to a service zone via a $lookup pipeline with a geo filter. [source] — AI-suggested, synthesized from this pack's existing facts — not extracted from a source document.
- Debugging a geospatial query that returns unexpected results, often traceable to longitude/latitude ordering or a missing or wrong index type. [source] — AI-suggested, synthesized from this pack's existing facts — not extracted from a source document.
Project ideas
- Build a "find nearby" endpoint using $geoNear as the first aggregation stage to return sorted results with the computed distance attached, then convert units with distanceMultiplier. [source] — AI-suggested, synthesized from this pack's existing facts — not extracted from a source document.
- Build a delivery-zone lookup service that denormalizes a zone or region ID onto each document at write time, rather than computing $geoWithin per query, to eliminate the per-row geo scan at read time. [source] — AI-suggested, synthesized from this pack's existing facts — not extracted from a source document.
- Implement route or region overlap detection with $geoIntersects backed by a 2dsphere index, useful for checking whether a delivery route crosses a restricted zone. [source] — AI-suggested, synthesized from this pack's existing facts — not extracted from a source document.
- Build a hot-path proximity search on Atlas Search using a geoWithin or geoShape filter instead of the aggregation pipeline, for workloads where dedicated search-index performance matters more than pipeline flexibility. [source] — AI-suggested, synthesized from this pack's existing facts — not extracted from a source document.
Antipatterns
- Storing coordinates as [lat, lng] instead of GeoJSON's required [lng, lat] order — a swap that silently produces wrong results rather than an error. [source] — AI-suggested, synthesized from this pack's existing facts — not extracted from a source document.
- Using a legacy 2d index for real-world geographic data, when 2d assumes flat-earth planar geometry and doesn't handle anti-meridian wraparound or spherical distance correctly. [source] — AI-suggested, synthesized from this pack's existing facts — not extracted from a source document.
- Running $geoIntersects or $geoWithin inside a $lookup pipeline against a large joined collection without a 2dsphere index on the joined field, turning the join into an unindexed per-row geo scan. [source] — AI-suggested, synthesized from this pack's existing facts — not extracted from a source document.
- Nesting multiple $near or $nearSphere expressions inside $or or $and — both operators require being the sole query predicate and will reject that combination. [source] — AI-suggested, synthesized from this pack's existing facts — not extracted from a source document.
Known issues
- 2dsphere indexes are always effectively sparse — a document with a missing, null, or empty-array geo field is silently excluded from the index, even if the sparse option itself isn't set. [source] — AI-suggested, synthesized from this pack's existing facts — not extracted from a source document.
- $geoWithin does not sort results and doesn't strictly require a geospatial index, but performance degrades badly on large collections without one, which can mask itself as a "correct but slow" query rather than an obvious missing-index error. [source] — AI-suggested, synthesized from this pack's existing facts — not extracted from a source document.
- $geoNear must be the first stage of its aggregation pipeline, which constrains how it can be combined with earlier filtering — any pre-filtering has to happen through the stage's own query option, not an earlier $match. [source] — AI-suggested, synthesized from this pack's existing facts — not extracted from a source document.
- Geospatial query operators like $geoIntersects, $geoWithin, and $near cannot be used inside $expr, since they are query operators, not aggregation expression operators — a common point of confusion when building $lookup pipelines. [source] — AI-suggested, synthesized from this pack's existing facts — not extracted from a source document.
Children
- 2dsphere Indexes
- 2d Indexes
- $geoNear Aggregation Stage
- $geoWithin and $centerSphere
- $geoIntersects
- $near and $nearSphere
- GeoJSON Object Types (frontier, viability 3.73 / 5)
- Radius Unit Conversions (frontier, viability 3.67 / 5)
- Geospatial $lookup Patterns (frontier, viability 2.70 / 5, below research gate)
- Geospatial Anti-Patterns (frontier, viability 3.67 / 5)
Frontier under this node: GeoJSON Object Types (3.73), Geospatial $lookup Patterns (2.70), Geospatial Anti-Patterns (3.67), Radius Unit Conversions (3.67)