Можете да използвате рамката за агрегиране за това и няма реално наказание, тъй като операциите са по същество едни и същи.
Но докато mongoose .find()
в момента има проблем с $nearSphereкод>
оператор, който е еквивалентен, винаги можете да вземете необработения обект за свързване на драйвера на възел и да направите вашата заявка.
Дори не е нужно да изхвърляте неща като „популация“, ако сте готови да приложите малко обработка.
Ето моите тестови данни:
{
"_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")
}
И основният код за справяне с това:
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 ) );
});
});
}
);
Така че можете да използвате и двете пропускане илимит операции върху курсора, имаше върнат курсор и дори обработи документите обратно в „Mongoose Documents“, така че можете да извиквате функции като .populate()
върху тях.
Очаквам текущия проблем с $nearSphereкод>
обаче ще бъде коригирано сравнително скоро.
Или вместо това да използвате агрегат:
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 ) );
});
}
);
Където можете да правите същите неща, като например да използвате .populate()
. И двата случая връщат резултати като този със съвпадение на „попълненото“ поле:
{
"_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
]
}
}
Разбира се, ако не се нуждаете от изчислението на сферичната геометрия, тогава $близо
Оператор работи перфектно с имплементацията на Mongoose на .find()