MongoDB’s geospatial indexes are surprisingly effective at finding nearby points, but they don’t work like you might expect if you’re used to traditional database indexes.

Let’s see this in action with a simple example. Imagine we have a collection of restaurants with their location as a GeoJSON Point:

{
  "_id": ObjectId("60c72b2f9f1b2c001a8e4f7a"),
  "name": "The Cozy Cafe",
  "location": {
    "type": "Point",
    "coordinates": [-73.9857, 40.7484]
  }
}

Now, we want to find all restaurants within 1000 meters of a specific point, say, near Times Square (coordinates: [-73.9857, 40.7484]).

First, we need a geospatial index on the location field. For 2dsphere indexes (which support spherical geometry and are generally preferred for their accuracy on a sphere like Earth), this is straightforward:

db.restaurants.createIndex({ "location": "2dsphere" })

With the index in place, we can perform a $geoWithin query. This operator finds documents whose GeoJSON geometry is entirely within a specified shape. To find points within a radius, we can use a circle, which is represented by a GeoJSON Polygon where the first and last points are identical, and the intermediate points define the circle’s boundary. MongoDB provides a helper function, $geometry with $centerSphere, to construct this.

Here’s the query to find restaurants within 1000 meters of Times Square:

db.restaurants.find({
  "location": {
    $geoWithin: {
      $geometry: {
        type: "Polygon",
        coordinates: [[
          [-73.9857, 40.7484], // Center point
          [-73.9857 + (1000 / 3963.2) * (180 / Math.PI), 40.7484], // East
          [-73.9857, 40.7484 + (1000 / 3963.2) * (180 / Math.PI)], // North (approximate for illustration)
          [-73.9857 - (1000 / 3963.2) * (180 / Math.PI), 40.7484], // West
          [-73.9857, 40.7484 - (1000 / 3963.2) * (180 / Math.PI)], // South (approximate for illustration)
          [-73.9857, 40.7484] // Close the polygon
        ]]
      }
    }
  }
})

Note: The above polygon construction is illustrative. For precise calculations, you’d use $centerSphere as shown below, which is the more common and accurate approach for radius-based queries.

A more direct and commonly used method for radius queries with a 2dsphere index is using the $nearSphere operator. It finds documents whose coordinates are within a specified distance from a point.

db.restaurants.find({
  "location": {
    $nearSphere: {
      $geometry: {
        type: "Point",
        coordinates: [-73.9857, 40.7484]
      },
      $maxDistance: 1000 // in meters
    }
  }
})

This query tells MongoDB: "Find documents where the location field is a point, and that point is within 1000 meters of the given coordinates. Use the 2dsphere index for this calculation." The $maxDistance parameter is crucial here.

The core problem these indexes solve is efficiently querying spatial data. Without them, finding all points within a radius would involve a full collection scan, calculating the distance from every single document’s location to the query point, and then filtering. For large datasets, this is prohibitively slow. A 2dsphere index, on the other hand, structures the Earth’s surface into a hierarchical grid (using a Z-order curve or similar encoding) that allows MongoDB to quickly identify potential matches and discard vast portions of the index that are outside the query’s bounding box. It’s like having a pre-sorted, multi-dimensional map of your data.

The 2dsphere index is particularly interesting because it treats the Earth as a sphere, accounting for curvature. This means queries are accurate even across the poles or the International Date Line. For flatter, 2D plane queries where Earth’s curvature is negligible (e.g., within a small city block), a 2d index can be used, but 2dsphere is generally recommended for real-world geographic data.

When you perform a $nearSphere or $geoWithin query with a 2dsphere index, MongoDB doesn’t just look for points within a bounding box. It actually uses the index to subdivide the sphere into regions. For a radius query, it finds the smallest set of index cells that completely contain the query circle. Then, it retrieves documents from those cells and performs a precise distance calculation to filter out any false positives that might have fallen into the cell but are outside the exact radius.

What most people don’t realize is that $nearSphere (and $near for 2d indexes) inherently sorts the results by distance. If you omit a sort() clause, MongoDB will return the documents ordered from nearest to farthest from the query point. This is a powerful side effect of how the index is traversed during the query.

The next step after mastering basic proximity queries is understanding how to query polygons or lines, or how to combine geospatial queries with other filter criteria for more complex location-based filtering.

Want structured learning?

Take the full Mongodb course →