Du kan använda aggregeringsramverket för detta och det finns ingen verklig påföljd eftersom operationerna i huvudsak är desamma.
Men medan mangusten .find()
metod har för närvarande ett problem med $nearSphere
operatör som är likvärdig, kan du alltid ta tag i anslutningsobjektet för rånoddrivrutinen och göra din fråga.
Du behöver inte ens slänga saker som "befolkning" om du är beredd att genomföra lite hantering.
Här är mina testdata:
{
"_id" : "P1",
"amenity" : "restaurant",
"shape" : {
"type" : "Point",
"coordinates" : [ 2, 2 ]
}
}
{
"_id" : "P3",
"amenity" : "police",
"shape" : {
"type" : "Point",
"coordinates" : [ 4, 2 ]
}
}
{
"_id" : "P4",
"amenity" : "police",
"shape" : {
"type" : "Point",
"coordinates" : [ 4, 4 ]
}
}
{
"_id" : "P2",
"amenity" : "restaurant",
"shape" : {
"type" : "Point",
"coordinates" : [ 2, 4 ]
},
"info" : ObjectId("539b90543249ff8d18e863fb")
}
Och den grundläggande koden för att hantera detta:
var mongoose = require('mongoose'),
async = require('async'),
Schema = mongoose.Schema;
mongoose.connect('mongodb://localhost');
var infoSchema = new Schema({
"description": String
});
var shapeSchema = new Schema({
"_id": String,
"amenity": String,
"shape": {
"type": { "type": String },
"coordinates": []
},
"info": { "type": Schema.Types.ObjectId, "ref": "Info" }
});
var Shape = mongoose.model( "Shape", shapeSchema );
var Info = mongoose.model( "Info", infoSchema );
Shape.collection.find(
{
"shape": {
"$nearSphere": {
"$geometry": {
"type": "Point",
"coordinates": [ 2, 4 ]
}
}
}
},
{
"skip": 0, "limit": 2
},
function(err,cursor) {
cursor.toArray(function(err,shapes) {
Shape.populate( shapes, { path: "info" }, function(err,docs) {
if (err) throw err;
console.log( JSON.stringify( docs, undefined, 4 ) );
});
});
}
);
Så där fick du användning av både hopp och gräns operationer på markören, fick en markör att returnera och till och med bearbetade dokumenten tillbaka till "Mongoose Documents" så att du kan anropa funktioner som .populate()
på dem.
Jag förväntar mig det aktuella problemet med $nearSphere
ska fixas relativt snart dock.
Eller använd aggregat istället:
Shape.aggregate(
[
{ "$geoNear": {
"near": {
"type": "Point",
"coordinates": [ 2, 4 ]
},
"spherical": true,
"distanceField": "dis"
}},
{ "$skip": 0 },
{ "$limit": 2 }
],
function(err,shapes) {
if (err) throw err;
//console.log( shapes );
shapes = shapes.map(function(x) {
delete x.dis;
return new Shape( x );
});
Shape.populate( shapes, { path: "info" }, function(err,docs) {
if (err) throw err;
console.log( JSON.stringify( docs, undefined, 4 ) );
});
}
);
Där du kan göra samma saker som att använda .populate()
. Båda fallen ger resultat som detta med det "fyllda" fältet matchat:
{
"_id": "P2",
"amenity": "restaurant",
"info": {
"_id": "539b90543249ff8d18e863fb",
"description": "Jamies Restaurant",
"__v": 0
},
"shape": {
"type": "Point",
"coordinates": [
2,
4
]
}
},
{
"info": null,
"_id": "P4",
"amenity": "police",
"shape": {
"type": "Point",
"coordinates": [
4,
4
]
}
}
Naturligtvis om du inte behöver beräkningen av sfärisk geometri är $nära
operatorn fungerar perfekt med Mongoose-implementeringen av .find()