How to use geolocation in Mongoose (with examples)

Updated: December 31, 2023 By: Guest Contributor Post a comment

Introduction

Geolocation is an essential capability for many modern web applications, such as those that provide location-based services. Mongoose, combined with MongoDB, can be an effective tool for storing and querying geospatial data. This tutorial will guide you through the process of using geolocation features in Mongoose effectively, with practical examples.

Before getting started, you need to have:

  • Basic knowledge of Node.js and npm
  • Familiarity with MongoDB and Mongoose
  • An instance of MongoDB installed and running

Setting Up Mongoose with a Geospatial Schema

In MongoDB, geospatial data can be stored as GeoJSON objects. Here’s how you can set up a Mongoose schema with geolocation fields:

// Step 1: Import Mongoose
c
const mongoose = require('mongoose');

// Step 2: Create a GeoSchema
const GeoSchema = new mongoose.Schema({
  type: {
    type: String,
    default: 'Point'
  },
  coordinates: {
    type: [Number],
    index: '2dsphere'
  }
});

// Step 3: Create a Model with GeoSchema
const YourModel = mongoose.model('YourModel', new mongoose.Schema({
  name: String,
  location: GeoSchema
}));

Inserting Geospatial Data

Let’s insert some documents containing geospatial data:

// Example document
const place = new YourModel({
  name: 'Awesome Place',
  location: {
    type: 'Point',
    coordinates: [-73.856077, 40.848447]
  }
});

// Saving the document with geospatial data
place.save(function (err) {
  if (err) console.log(err);
  console.log('Place saved!');
});

Querying Geospatial Data

To find documents within a certain distance from a point, you can use MongoDB’s geospatial query operators. Here’s an example of a proximity search:

// Finding places within 10 kilometers from a point
YourModel.find({
  location: {
    $near: {
      $geometry: {
        type: 'Point',
        coordinates: [-73.856077, 40.848447]
      },
      $maxDistance: 10000
    }
  }
}).then(places => {
  console.log('Found places:', places);
}).catch(err => {
  console.log(err);
});

Indexing Geospatial Fields

For optimal performance, it’s important to index geospatial fields. Here’s how you do that:

// Step 1: Define Index on Schema
GeoSchema.index({ coordinates: '2dsphere' });

// Step 2: Use the index in queries
c
// Mongoose will automatically use the defined index for geospatial queries

Advanced Geospatial Queries

Beyond basic proximity searches, MongoDB supports various other geospatial queries. Let’s explore a few advanced use cases:

Finding Geometries within a Range

// Usage of $geoWithin to find geometries within a specified region
const region = {
  type: 'Polygon',
  coordinates: [ /* Array of coordinate arrays */ ]
};

YourModel.find({
  location: {
    $geoWithin: {
      $geometry: region
    }
  }
}).then(places => {
  console.log('Found places within region:', places);
}).catch(err => {
  console.log(err);
});

Calculating Distances

// Usage of $geoNear to calculate distances
c
YourModel.aggregate([
  {
    $geoNear: {
      near: { type: 'Point', coordinates: [ -73.856077, 40.848447 ] },
      distanceField: 'dist.calculated',
      maxDistance: 10000
    }
  }
]).then(results => {
  console.log(results);
}).catch(err => {
  console.log(err);
});

Spherical Geometry Calculations

// Usage of $geoIntersects for spherical geometry calculations
c
YourModel.find({
  location: {
    $geoIntersects: {
      $geometry: {
        type: 'LineString',
        coordinates: [ /* An array of coordinates representing a line */ ]
      }
    }
  }
}).then(places => {
  console.log('Found places intersecting the line:', places);
}).catch(err => {
  console.log(err);
});

Conclusion

Now that we’ve explored the essentials of handling geolocation in Mongoose through comprehensive examples, you’re well on your way to integrating these functionalities in your own location-based services. Remember, the secret lies in the schema setup, proper indexing, and leveraging the powerful geospatial queries available in MongoDB and Mongoose.