Mongodb 地理位置索引

Mongodb 地理位置索引

Geospatial Indexing

     MongoDB支持二维空间索引,这是设计时考虑到基于位置的查询。例如“找到离目标位置最近的N条记录”。可以有效地作为附加条件过滤。

     如果需要使用这种索引,应确定对象中存储的字段是子对象或数组,前两个元素为X,Y坐标(或者Y,X坐标,保持一致即可。it might be advisible to use order-preserving dictionaries/hashes in your client code, to ensure consistency),一些例子:

 

Mongo代码  

{ loc : [ 50 , 30 ] }  

{ loc : { x : 50 , y : 30 } }  

{ loc : { foo : 50 , y : 30 } }  

{ loc : { lat : 40.739037, long: 73.992964 } }  

 

   Creating the Index

 

Mongo代码  

db.places.ensureIndex( { loc : "2d" } )     //应该是固定格式  

 

     默认的,Mongo假设你索引的是经度/维度,因此配置了一个从-180到180的取值范围,如果你想索引更多,可以指定该参数:

 

Mongo代码  

db.places.ensureIndex( { loc : "2d" } , { min : -500 , max : 500 } )  

 

     上面的代码将衡量索引保证存入的值在-500到500的范围之内。一般来说geo索引仅限于正方形以内且不包括边界以以外的范围,不能再边界上插入值,比如使用上面的代码,点(-500,-500)是不能被插入的。

 

     目前为止,每个Collection只能建立一个geo索引

 

    Querying

      该索引可以被用来精确匹配:

 

Mongo代码  

db.places.find( { loc : [50,50] } )  

 

     对于geo索引来说,更重要的是一个查询可以找到目标点附近的点,不必要精确匹配。

 

Mongo代码  

db.places.find( { loc : { $near : [50,50] } } )  

 

     上面的一句将按离目标点(50,50)距离最近的100个点(距离倒序排列),如果想指定返回的结果个数,可以使用limit()函数,若不指定,默认是返回100个。

 

Mongo代码  

db.places.find( { loc : { $near : [50,50] } } ).limit(20)  

 

    Compound Indexes

      Mongo空间索引可选的支持第二字段索引.如果想用坐标和其他属性同事作为条件查询,把这个属性也一同索引,其他属性带注释性的加入索引中可使过滤更快。

 

Mongo代码  

db.places.ensureIndex( { location : "2d" , category : 1 } );  

db.places.find( { location : { $near : [50,50] }, category : 'coffee' } );  

 

    geoNear Command

      虽然find()语法为查询的首选,Mongo也提供来了 geoNear 命令来执行相似的函数。geoNear命令有一个额外的好处是结果中返回距离目标点的距离,以及一些利于排除故障的信息。

Mongo代码  

> db.runCommand( { geoNear : "places" , near : [50,50], num : 10 } );  

> db.runCommand({geoNear:"asdf", near:[50,50]})  

{  

        "ns" : "test.places",  

        "near" : "1100110000001111110000001111110000001111110000001111",  

        "results" : [  

                {  

                        "dis" : 69.29646421910687,  

                        "obj" : {  

                                "_id" : ObjectId("4b8bd6b93b83c574d8760280"),  

                                "y" : [  

                                        1,  

                                        1  

                                ],  

                                "category" : "Coffee"  

                        }  

                },  

                {  

                        "dis" : 69.29646421910687,  

                        "obj" : {  

                                "_id" : ObjectId("4b8bd6b03b83c574d876027f"),  

                                "y" : [  

                                        1,  

                                        1  

                                ]  

                        }  

                }  

        ],  

        "stats" : {  

                "time" : 0,  

                "btreelocs" : 1,  

                "btreelocs" : 1,  

                "nscanned" : 2,  

                "nscanned" : 2,  

                "objectsLoaded" : 2,  

                "objectsLoaded" : 2,  

                "avgDistance" : 69.29646421910687  

        },  

        "ok" : 1  

}  

 

     上面的命令将返回10条距离点(50,50)最近的记录,loc字段由该collection的空间索引自动检测后决定。

     如果你想添加一条过滤条件,可以这样:

Mongo代码  

> db.runCommand( { geoNear : "places" , near : [ 50 , 50 ], num : 10,  

... query : { type : "museum" } } );  

 

    Bounds Queries

    v1.3.4版本以上

     $within 参数可以代替$near来查找一个形状之内结果。同时,也支持$box(矩形)和$center(圆环)

    想要查找一个一个矩形之内所有的点,必须制定该矩形的左下角和右上角坐标:

Mongo代码  

> box = [[40, 40], [60, 60]]  

> db.places.find({"loc" : {"$within" : {"$box" : box}}})  

 

更多信息请参考

http://www.mongodb.org/display/DOCS/Geospatial+Indexing 


Geospatial Query Operators

Operators

Query Selectors

Name Description
$geoWithin Selects geometries within a bounding GeoJSON geometry.
$geoIntersects Selects geometries that intersect with a GeoJSON geometry.
$near Returns geospatial objects in proximity to a point.
$nearSphere Returns geospatial objects in proximity to a point on a sphere.

Geometry Specifiers

Name Description
$geometry Specifies a geometry in GeoJSON format to geospatial query operators.
$maxDistance Specifies a distance to limit the results of $near and $nearSphere queries.
$center Specifies a circle using legacy coordinate pairs to $geoWithin queries when using planar geometry.
$centerSphere Specifies a circle using either legacy coordinate pairs or GeoJSON format for $geoWithin queries when using spherical geometry.
$box Specifies a rectangular box using legacy coordinate pairs for $geoWithin queries.
$polygon Specifies a polygon to using legacy coordinate pairs for $geoWithin queries.
$uniqueDocs Modifies a $geoWithin and $near queries to ensure that even if a document matches the query multiple times, the query returns the document once.

Geospatial Query Compatibility

While numerous combinations of query operators are possible, the following table shows the recommended operators for different types of queries. The table uses the $geoWithin$geoIntersects and $near operators.

Query Document Geometry of the Query Condition Surface Type for Query Calculation Units for Query Calculation Supported by this Index
Returns points, lines and polygons        
{ $geoWithin : {
  $geometry : <GeoJSON Polygon>
} }
polygon sphere meters 2dsphere
{ $geoIntersects : {
  $geometry : <GeoJSON>
} }
point, line or polygon sphere meters 2dsphere
{ $near : {
  $geometry : <GeoJSON Point>,
  $maxDistance : d
} }
point sphere meters

2dsphere

The index is required.

Returns points only        
{ $geoWithin : {
  $box : [[x1, y1], [x2, y2]]
} }
rectangle flat flat units 2d
{ $geoWithin : {
  $polygon : [[x1, y1],
              [x1, y2],
              [x2, y2],
              [x2, y1]]
} }
polygon flat flat units 2d
{ $geoWithin : {
  $center : [[x1, y1], r],
} }
circular region flat flat units 2d
{ $geoWithin : {
  $centerSphere :
    [[x, y], radius]
} }
circular region sphere radians

2d

2dsphere

{ $near : [x1, y1],
  $maxDistance : d
}

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值