2013-07-25 33 views
1

我想用$ 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) 

但我无法弄清楚如何访问一个蒙戈查询半径变量。这甚至有可能吗?

+0

您能否解释您的最终目标,以便我可以为您提供替代方案? – Derick

+0

与消防局的例子一起,我想结束一个foo.loc位于某个指定位置的foo.radius内的所有foo站点的列表。 就替代方案而言,如果它不是我可以用单个查询做的事情,我想我只会获取所有内容并自己进行距离比较。我要结束的文件数量实际上很小,所以这应该合理地执行。 – David

+0

请将该信息添加到问题中,而不仅仅是作为评论。但我已经更新了我的答案。 – Derick

回答

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位于多边形的中间。现在诀窍是计算构成距离中心点“半径”(比如说10公里)的圆的多边形点。你将无法获得真正的圈子,但六角形或八角形应该足够好。这个数学不是非常简单,但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 ], 
     ] ] 
    } 
} 
相关问题