我想用$ maxDistance参数写一个$ near查询,其值不是常量。例如,我有一个具有位置和覆盖半径的消防站的集合,我想找到其覆盖半径包括某个特定点的所有消防站。覆盖范围半径可能因电台而异。
我的馆藏文件如下:
{
'loc' : [-72,40],
'radius' : 10
}
类似于以下内容的查询:
{'loc': { $near : coordinates, $maxDistance : 'radius'}};
但这不正确。
如果我正在编写SQL查询,我会使用类似的东西:
SELECT * FROM table AS foo WHERE foo.radius ... (whatever your distance method looks like)
但我无法弄清楚如何在mongo查询中访问该radius变量。这甚至可能吗?
答案 0 :(得分:0)
你不能这样做 - 通常你不能在MongoDB查询中基于集合中的值做任何事情。
然而,由于MongoDB 2.4我们支持一个名为2dsphere
的新索引,它不仅可以存储数据库中的点,还可以存储多边形。您将该信息存储在如下文档中:
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 ] ] ]
}
} );
然后你可以使用“交叉”查询来确定每个多边形是否覆盖了一个点:
db.so.find( {
'loc' : {
$geoIntersects: {
$geometry: { type: 'Point', coordinates: [ 0, 0 ] }
}
}
} );
然后返回:
{
"_id" : ObjectId("51f24d566775068ab0b786f0"),
"name" : "Firestation 1",
"loc" : {
"type" : "Polygon",
"coordinates" : [ [ [ 0, 0 ], [ 0, 1 ], [ 1, 1 ], [ 1, 0 ], [ 0, 0 ] ] ]
}
}
这里找到了消防站,因为0,0位于多边形的中间。现在的诀窍当然是计算构成一个距离中心点“半径”(比如说10km)的圆的多边形点。你将无法得到一个真正的圆,但六边形或八边形应该足够好。数学并不是非常简单,但http://www.movable-type.co.uk/scripts/latlong.html#destPoint在JavaScript中有一个例子。 只需将轴承从0到2PI以8个步长循环,以计算沿圆周的点,并将它们放在坐标中。确保将它们嵌入到双嵌套数组中,并使第一个和最后一个相同:
{
name: "Firestation 1",
loc: {
type: "Polygon",
coordinates: [ [
[ point1-lon, point1-lat ],
[ point2-lon, point2-lat ],
[ point3-lon, point3-lat ],
...
[ point1-lon, point1-lat ],
] ]
}
}