Nếu bạn muốn một giản đồ hỗ trợ GeoJSON, trước tiên bạn cần phải xây dựng lược đồ đó đúng cách:
var userSchema = new Schema({
loc: {
type: { type: String },
coordinates: [Number],
}
});
Điều đó đảm bảo rằng không có sự nhầm lẫn với từ khóa "loại" của định nghĩa lược đồ. Nếu bạn thực sự muốn hỗ trợ toàn bộ các loại GeoJSON, thì bạn có thể nới lỏng hơn một chút:
var userSchema = new Schema({
loc: {
type: { type: String },
coordinates: []
}
});
Tiếp theo, bạn muốn gắn một chỉ mục với shema:
userSchema.index({ "loc": "2dsphere" });
Sau đó, tất nhiên xác định một mô hình và lưu trữ mọi thứ một cách chính xác:
var User = mongoose.model( "User", userSchema );
var user = new User({
"loc": {
"type": "Point",
"coordinates": [-73.97, 40.77]
}
});
Lưu ý rằng dữ liệu của bạn phải ở kinh độ sau đó đến vĩ độ đặt hàng như được hỗ trợ bởi GeoJSON và tất cả các biểu mẫu truy vấn không gian địa lý MongoDB.
Tiếp theo, thay vì đào sâu vào cách sử dụng khó hiểu của các lệnh cơ sở dữ liệu trực tiếp trên phương thức trình điều khiển thô, thay vào đó hãy sử dụng những thứ được hỗ trợ trực tiếp và tốt hơn. Chẳng hạn như $geoNear
cho .aggregate()
phương pháp:
User.aggregate(
[
{ "$geoNear": {
"near": {
"type": "Point",
"coordinates": [<long>,<lat>]
},
"distanceField": "distance",
"spherical": true,
"maxDistance": 10000
}}
],
function(err,results) {
}
)
Và bây giờ vì dữ liệu là GeoJSON, khoảng cách đã được chuyển đổi thành mét nên không cần thực hiện công việc chuyển đổi khác.
Cũng xin lưu ý rằng bạn đã nhầm lẫn với điều này, trừ khi bạn bỏ bộ sưu tập, bất kỳ chỉ mục nào bạn đã thử sẽ vẫn ở đó và điều đó có thể gây ra sự cố.
Bạn có thể loại bỏ tất cả các chỉ mục từ bộ sưu tập trong mongodb shell một cách dễ dàng:
db.users.dropIndexes();
Hoặc vì bạn có thể cần phải định hình lại dữ liệu, sau đó bỏ bộ sưu tập và bắt đầu lại:
db.users.drop();
Thiết lập mọi thứ đúng cách và bạn sẽ không gặp vấn đề gì.