Sling Academy
Home/Node.js/How to use geolocation in Mongoose (with examples)

How to use geolocation in Mongoose (with examples)

Last updated: December 31, 2023

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.

Next Article: Mongoose: Server Discovery And Monitoring Engine is Deprecated

Previous Article: Mongoose: Find Documents Where a Field Is Not Null or Empty

Series: Mongoose.js Tutorials

Node.js

You May Also Like

  • NestJS: How to create cursor-based pagination (2 examples)
  • Cursor-Based Pagination in SequelizeJS: Practical Examples
  • MongooseJS: Cursor-Based Pagination Examples
  • Node.js: How to get location from IP address (3 approaches)
  • SequelizeJS: How to reset auto-increment ID after deleting records
  • SequelizeJS: Grouping Results by Multiple Columns
  • NestJS: Using Faker.js to populate database (for testing)
  • NodeJS: Search and download images by keyword from Unsplash API
  • NestJS: Generate N random users using Faker.js
  • Sequelize Upsert: How to insert or update a record in one query
  • NodeJS: Declaring types when using dotenv with TypeScript
  • Using ExpressJS and Multer with TypeScript
  • NodeJS: Link to static assets (JS, CSS) in Pug templates
  • NodeJS: How to use mixins in Pug templates
  • NodeJS: Displaying images and links in Pug templates
  • ExpressJS + Pug: How to use loops to render array data
  • ExpressJS: Using MORGAN to Log HTTP Requests
  • NodeJS: Using express-fileupload to simply upload files
  • ExpressJS: How to render JSON in Pug templates