快速了解mongodb的空间操作
Minbin Jiang Lv4

遥想当年做毕业设计的时候,为了写论文而写论文,定了个mongodb 与oracle的互操作。当时使用的mongodb是无法对空间数据进行操作的。当时单纯的使用GDAL将shapelife文件转换文本表达以mongodb进行存储。

而现在看mongodb的空间操作,虽然没有办法和ArcSDE和PostGIS相比,但是比没有强呀。

文中使用的mongodb为2.4版本,robomongo0.9

##空间数据模型

mongodb中有两类空间平面,一个是spherical,也是我们GIS中所熟悉的,另外一类就是纯粹的Euclidean平面。

针对Eulidena平面下的空间数据使用legacy coordinate pairs的形式进行表达。其格式为[x,y]形式。表达polygon什么的需要和monodb的Geometry Specifiers 来配合,如

$polygon : [ [ 0 , 0 ] , [ 0 , 1 ] , [ 1 , 1 ] , [ 1 , 0 ] ]
另一种是地球相关的面,采用的geojson的形式。mongodb从2.4开始支持geojson,到2.6 geojson的几何类型基本可以全部表达。

有关geojson标准可以参考:需要了解的geojson和操作工具

本文肯定是使用geojson的。。

##空间索引

mongodb的空间索引有三类,针对不同的情形。有的操作是必须要指定采用的索引类型。

  • 2d Index针对mongodb 2.2 以前的版本数据使用legancy coordinate pairs存储。
  • 2d Sphere Index 用来对sphere的数据进行构建索。本文我们肯定是使用这个索引得。
  • Geo Haystack适合用来对小范围的数据进行索引。在Euclide平面中使用的效率比sphere的效率高。

##数据准备

###创建geojson数据
为了简便,通过 geojson.io在线网站中生成本次实验的geojson。数据情形如下图所示

###mongodb将数据入库

建立了三个collection,并将每个feature以一个document的形式插入。Geometry的key为“loc”。如下所示

db.testpoint.insert({
 "name":'point1',
 "loc":{
  { "type": "Point",
  "coordinates": [100.0, 0.0] }
 }})

结果如下图所示。

空间查询操作

目前mongodb的空间查询类操作只包含如下三大类:

  • 包含查询($geoWithin)

查询名称polgon1的polygon所包含的点:

var polygon=db.testpolygon.findOne({"name":"polgon1"})

db.testpoint.find({
   loc : { $geoWithin : { $geometry : polygon.loc } } 
    })

$geoWithin 可不需要指定spatial index,但是为了效率,建议对空间字段建立index

  • 相交查询($geoIntersects)

选择与某个多边形相交的几何对象。比如,选中与面相交的线

var polygon=db.testpolygon.findOne({"name":"polgon1"})
db.testline.find({
loc:{ $geoIntersects:{$geometry:polygon.loc}}
})

同样其不需要构建索引,但是从效率的角度建议构建。

  • 临近查询($near,$nearSphere)

用来查找离某个点一定距离的点。需要构建索引

使用 db.testpoint.ensureIndex("2dsphere")

创建索引。

然后使用$neare 操作符号进行选择,如选择离点id1,最大不超过500公里的点。

var point=db.testpoint.findOne({"name":"id1"})
db.testpoint.find({
    loc: {$near: {
           $geometry: point.loc,
           $maxDistance: 500000,
        }}
    })

返回的记录按照距离的从近到远进行排列。

##更多参考

Geospatial Indexes and Queries

A Primer on Geospatial Data and MongoDB

tug’s blog introduction-to-mongodb-geospatial