在mongodb地理定位查询中使用object属性作为$ maxDistance参数

时间:2013-07-25 20:49:13

标签: javascript mongodb geolocation

我想用$ 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变量。这甚至可能吗?

1 个答案:

答案 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 ], 
        ] ]
    }
}