mongodb map减少了postgis查询的等价物

时间:2014-06-14 23:06:31

标签: mongodb mapreduce postgis

在postgis查询之后,为所有点创建缓冲区,然后获取与用户位置相交的点(也由常量值缓冲):

SELECT id, created_at, ST_AsGeoJSON(the_geom) FROM table WHERE ST_INTERSECTS(ST_Buffer(ST_GeomFromText('POINT(x y)',4326)::geography, 150)::geometry, 
ST_Buffer(the_geom::geography, 100*(seenCount+1))::geometry) ORDER BY created_at DESC

我想将我们的数据库迁移到mongodb,但我找不到如何在mongodb中实现上述查询。

1 个答案:

答案 0 :(得分:1)

MongoDB中没有等效的ST_Buffer,它在可执行的空间查询类型中仍然非常有限,主要限于运算符内部,相交和近运算符,请参阅:MongoDB geospatial query operators

一种方法是将你的字段the_geom保存为预先缓冲的GeoJSON多边形,然后你就可以使用2dsphere index来查找与点的某个缓冲区相交的任何内容,例如,

db.points.find(
    {geom:
      {$geoIntersects:
        {$geometry:
          {type:"Polygon", 
            coordinates:[[[49, 50],[50,51],[51,50],[50,49],[49,50]]]
          }
        }
      }
   }
)

其中坐标表示点的某个缓冲区。在lat / lon的小距离上,您可以模拟带圆的点的缓冲区,但失真会随缓冲区大小和宽容度而增加。如果你需要更高的精度,你必须在插入MongoDB之前在WGS 84椭球体上正确计算缓冲区 - 很难推荐任何库而不知道你将用什么客户端与Mongo交互。

当然,你也可以通过map-reduce来做到这一点,只需计算每个点和每个多边形之间的距离。对于球体上的精确距离测量,请查看Vincenty距离,有关一种实现,请参阅 OpenLayers distVincenty Javascript function.。如果两个几何之间的Vincenty距离小于一起添加的两个缓冲区的值,则可以模拟两个缓冲区的交集。

我怀疑map-reduce方法会很慢,因为它不会使用任何空间索引,但如果时间不是问题,并且你不想要额外的缓冲点开销并保存它们作为GeoJSON多边形,它会起作用。

除此之外,还有关于将Java拓扑套件库的许可证更改为BSD的邮件列表的讨论,这意味着如果推动添加更多空间功能,MongoDB理论上可以包含其功能。 Java拓扑套件,在其C ++端口GEOS中,是提供Postgis中许多空间关系运算符的库。