Using GeoJSON
The most simple structure in GeoJSON is a point. Below is an example point representing the approximate location of . Note that longitude comes first in a GeoJSON coordinate array, not latitude.
Below is an example of a Mongoose schema where is a point.
const citySchema = new mongoose.Schema({
name: String,
location: {
type: {
type: String, // Don't do `{ location: { type: String } }`
enum: ['Point'], // 'location.type' must be 'Point'
required: true
},
coordinates: {
type: [Number],
required: true
}
}
});
Using subdocuments, you can define a common pointSchema
and reuse it everywhere you want to store a GeoJSON point.
const pointSchema = new mongoose.Schema({
type: {
type: String,
enum: ['Point'],
required: true
},
coordinates: {
type: [Number],
required: true
}
});
const citySchema = new mongoose.Schema({
name: String,
location: {
type: pointSchema,
}
});
Polygons are tricky because they use triple nested arrays. Below is how you create a Mongoose schema where coordinates
is a triple nested array of numbers.
const polygonSchema = new mongoose.Schema({
type: {
type: String,
enum: ['Polygon'],
required: true
},
coordinates: {
type: [[[Number]]], // Array of arrays of arrays of numbers
required: true
}
});
const citySchema = new mongoose.Schema({
name: String,
location: polygonSchema
});
Mongoose queries support the same that the MongoDB driver does. For example, the below script saves a city
document those location
property is a GeoJSON point representing the city of Denver, Colorado. It then queries for all documents within a polygon representing the state of Colorado using the MongoDB $geoWithin
operator.
const City = db.model('City', new Schema({
name: String,
location: pointSchema
}));
const colorado = {
coordinates: [[
[-109, 41],
[-102, 37],
[-109, 37],
[-109, 41]
]]
};
const denver = { type: 'Point', coordinates: [-104.9903, 39.7392] };
return City.create({ name: 'Denver', location: denver }).
then(() => City.findOne({
location: {
$geoWithin: {
$geometry: colorado
}
}
})).
then(doc => assert.equal(doc.name, 'Denver'));
MongoDB supports for speeding up geospatial queries. Here’s how you can define a 2dsphere index on a GeoJSON point:
const denver = { type: 'Point', coordinates: [-104.9903, 39.7392] };
const City = db.model('City', new Schema({
name: String,
location: {
type: pointSchema,
index: '2dsphere' // Create a special 2dsphere index on `City.location`
}
}));
return City.create({ name: 'Denver', location: denver }).
then(() => City.findOne().where('location').within(colorado)).
You can also define a geospatial index using the Schema#index()
function as shown below.
citySchema.index({ location: '2dsphere' });
MongoDB’s and $geoNear
aggregation stage require a 2dsphere index.