Create & Find GeoLocation in mongoose
If you want a schema to support GeoJSON, the you first need to construct that properly:
var userSchema = new Schema({
loc: {
type: { type: String },
coordinates: [Number],
}
});
That makes sure there is no confusion with the "type" keyword of the schema defintition. If you really want to support the whole range of GeoJSON types, then you can make that a bit looser:
var userSchema = new Schema({
loc: {
type: { type: String },
coordinates: []
}
});
Next you want to tie an index to the shema:
userSchema.index({ "loc": "2dsphere" });
Then of course define a model and store things correctly:
var User = mongoose.model( "User", userSchema );
var user = new User({
"loc": {
"type": "Point",
"coordinates": [-73.97, 40.77]
}
});
Noting that your data must be in longitude then latitude order as supported by GeoJSON and all MongoDB geospatial query forms.
Next, rather than dig into obscure usages of database commands directly on the raw driver method, use things instead that are directly supported, and better. Such as $geoNear
for the .aggregate()
method:
User.aggregate(
[
{ "$geoNear": {
"near": {
"type": "Point",
"coordinates": [<long>,<lat>]
},
"distanceField": "distance",
"spherical": true,
"maxDistance": 10000
}}
],
function(err,results) {
}
)
And now because the data is GeoJSON, the distances are already converted to meters so there is no need to do other conversion work.
Also note that is you have been messing around with this, unless you drop the collection any index you tried will still be there and that will likely cause problems.
You can drop all indexes from the collection in the mongodb shell with ease:
db.users.dropIndexes();
Or since you likely need to do some data re-shaping, then drop the collection and start again:
db.users.drop();
Set things up properly and you will have no problems.