Bạn có thể sử dụng khung tổng hợp cho việc này và không có hình phạt thực sự nào vì các hoạt động về cơ bản giống nhau.
Nhưng trong khi mongoose .find()
phương pháp hiện có sự cố với $nearSphere
tương đương, bạn luôn có thể lấy đối tượng kết nối trình điều khiển nút thô và thực hiện truy vấn của mình.
Bạn thậm chí không cần phải vứt bỏ những thứ như "dân số" nếu bạn chuẩn bị thực hiện một chút xử lý.
Đây là dữ liệu thử nghiệm của tôi:
{
"_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")
}
Và mã cơ bản để xử lý điều này:
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 ) );
});
});
}
);
Vì vậy, bạn đã có cách sử dụng cả bỏ qua và giới hạn các hoạt động trên con trỏ, đã trả lại con trỏ và thậm chí xử lý các tài liệu trở lại thành "Mongoose Documents" để bạn có thể gọi các hàm như .populate()
trên chúng.
Tôi mong đợi sự cố hiện tại xảy ra với $nearSphere
sẽ được khắc phục tương đối sớm.
Hoặc sử dụng tổng hợp thay thế:
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 ) );
});
}
);
Nơi bạn có thể làm những việc tương tự như sử dụng .populate()
. Cả hai trường hợp đều trả về kết quả như thế này với trường "được điền" phù hợp:
{
"_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
]
}
}
Tất nhiên nếu bạn không cần tính toán hình cầu thì $near
toán tử hoạt động hoàn toàn tốt với việc triển khai Mongoose của .find()