Bạn hoàn toàn không thể làm điều này như thế này - nói chung bạn không thể căn cứ bất cứ điều gì trong các truy vấn MongoDB của mình trên các giá trị trong bộ sưu tập.
Tuy nhiên, kể từ MongoDB 2.4, chúng tôi hỗ trợ một chỉ mục mới có tên là 2dsphere
cho phép bạn lưu trữ không chỉ các điểm trong cơ sở dữ liệu mà còn lưu trữ cả các đa giác. Bạn sẽ lưu trữ thông tin đó trong một tài liệu như:
db.so.ensureIndex( { loc: '2dsphere' } );
db.so.insert( {
name: "Firestation 1",
loc: {
type: "Polygon",
coordinates: [ [ [ 0, 0 ], [ 0, 1 ], [ 1, 1 ], [ 1, 0 ], [ 0, 0 ] ] ]
}
} );
Và sau đó, bạn có thể sử dụng truy vấn "giao nhau" để tìm ra liệu một điểm có được bao phủ bởi mỗi đa giác hay không:
db.so.find( {
'loc' : {
$geoIntersects: {
$geometry: { type: 'Point', coordinates: [ 0, 0 ] }
}
}
} );
Sau đó trả về:
{
"_id" : ObjectId("51f24d566775068ab0b786f0"),
"name" : "Firestation 1",
"loc" : {
"type" : "Polygon",
"coordinates" : [ [ [ 0, 0 ], [ 0, 1 ], [ 1, 1 ], [ 1, 0 ], [ 0, 0 ] ] ]
}
}
Ở đây nó tìm thấy trạm cứu hỏa, vì 0, 0 nằm ở giữa đa giác. Bây giờ, mẹo tất nhiên là tính các điểm đa giác tạo thành một đường tròn cách tâm điểm "bán kính" (ví dụ 10km). Bạn sẽ không thể có được một hình tròn thực sự, nhưng một hình lục giác hoặc hình bát giác phải đủ tốt. Phép toán cho điều đó không cực kỳ đơn giản, nhưng http:// www.movable-type.co.uk/scripts/latlong.html#destPoint có một ví dụ trong JavaScript. Chỉ cần lặp vòng bi của bạn theo 8 bước từ 0 đến 2PI để tính toán các điểm dọc theo chu vi của vòng tròn và đưa các điểm đó vào tọa độ. Đảm bảo nhúng chúng vào một mảng lồng nhau kép và làm cho mảng đầu tiên và mảng cuối cùng giống nhau:
{
name: "Firestation 1",
loc: {
type: "Polygon",
coordinates: [ [
[ point1-lon, point1-lat ],
[ point2-lon, point2-lat ],
[ point3-lon, point3-lat ],
...
[ point1-lon, point1-lat ],
] ]
}
}