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.