Mongodb 地理位置索引

Mongodb 地理位置索引

Geospatial Indexingmongodb

     MongoDB支持二維空間索引,這是設計時考慮到基於位置的查詢。例如「找到離目標位置最近的N條記錄」。能夠有效地做爲附加條件過濾。json

     若是須要使用這種索引,應肯定對象中存儲的字段是子對象或數組,前兩個元素爲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 ] }  ui

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

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

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

 

   Creating the Indexcode

 

Mongo代碼  orm

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
}
相關文章
相關標籤/搜索