MongoDB: Calculating the Distance between 2 Locations

Updated: February 1, 2024 By: Guest Contributor Post a comment

Introduction

MongoDB is a popular NoSQL database that is known for its flexibility, scalability, and wide range of features, including geospatial queries. It has built-in support for storing and querying geospatial data, making it an excellent choice for applications that need to calculate distances between locations or query data based on location. This tutorial will cover how to calculate distances between two locations in MongoDB.

Prerequisites

  • Basic knowledge of MongoDB
  • MongoDB server installation
  • A database and collection with geospatial data

Understanding Geospatial Data in MongoDB

Before we dive into the calculations, let’s understand the geospatial data types that MongoDB supports:

  • 2D Index: This is suitable for flat surfaces like maps. It’s ideal for small to medium-sized area calculations.
  • 2D Sphere Index: Used for calculations involving spherical surfaces like Earth. This index considers the curvature of the Earth and provides more accurate results for larger distances.
  • GeoJSON: A format for encoding a variety of geographic data structures, including points, lines, and polygons.

Storing Geospatial Data

Let’s assume we have a collection called places, which contains documents with locations in GeoJSON format:

{
  name: 'Statue of Liberty',
  location: { type: 'Point', coordinates: [ -74.0445, 40.6892 ] }
}

To work with geospatial queries, you first need to create a geospatial index:

db.places.createIndex({ location: '2dsphere' });

Calculating Distance with the $geoNear Operator

The $geoNear aggregation stage is used to find the distance between two points. Here’s how to use it:

db.places.aggregate([
  {
    $geoNear: {
      near: { type: 'Point', coordinates: [ ,  ] },
      distanceField: 'dist.calculated',
      spherical: true
    }
  }
]);

Replace <longitude> and <latitude> with the coordinates of the location you’re calculating the distance from.

Calculating Distance Manually

For more control over the calculation, you can use MongoDB’s aggregation framework to manually calculate distances. You’ll need to convert your coordinates to radians and use trigonometric formulas to compute the distance. The Haversine formula is commonly used:

const R = 6378.1; // Earth's radius in km

const toRadians = (degree) => degree * (Math.PI / 180);

const haversine = (lat1, lon1, lat2, lon2) => {
  const dLat = toRadians(lat2 - lat1);
  const dLon = toRadians(lon2 - lon1);
  const a =
    Math.sin(dLat / 2) * Math.sin(dLat / 2) +
    Math.cos(toRadians(lat1)) * Math.cos(toRadians(lat2)) *
    Math.sin(dLon / 2) * Math.sin(dLon / 2);
  const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
  const distance = R * c;

  return distance;
};

const distance = haversine(40.6892, -74.0445, , );
print('Distance in kilometers:', distance);

Again, replace <latitude> and <longitude> with the coordinates of the second location.

Using $geoNear to Return Documents within a Specific Distance

If you want to find documents within certain proximity, use the maxDistance parameter of the $geoNear operator:

db.places.aggregate([
  {
    $geoNear: {
      near: { type: 'Point', coordinates: [ ,  ] },
      distanceField: 'dist.calculated',
      maxDistance: ,
      spherical: true
    }
  }
]);

The above query will return documents that are within <max_distance_in_meters> meters of the supplied location.

Conclusion

Calculating distances between geolocations is a common requirement for location-based services and MongoDB provides robust support for such operations. This tutorial covered the basics of geospatial data, indexing, and distance calculations in MongoDB using both the $geoNear operator and manual calculations with JavaScript functions. Leverage these approaches to build efficient, location-aware applications.