mongoDb地理空間索引和查詢

一.MongoDb介紹(http://docs.mongoing.com/manual/applications/geospatial-indexes.html)html

MongoDB提供了一系列的索引和查詢機制來處理地理空間信息。這一節會介紹MongoDB的地理索引特性。您能夠閱讀 地理索引教程 來了解關於MongoDB中地理查詢的完整示例。git

表面

在您存儲地理數據和編寫查詢條件前,首先,您必須選擇表面類型,這將被用在計算中。您所選擇的類型將會影響您的數據如何被存儲,創建的索引的類型,以及您的查詢的語法形式。spring

MongoDB提供了兩種表面類型:mongodb

球面

若是須要計算地理數據就像在一個相似於地球的球形表面上,您能夠選擇球形表面來存儲數據,這樣就可使用 2dsphere 索引。shell

您能夠按照座標軸:經度,緯度 的方式把位置數據存儲爲GeoJSON對象。GeoJSON的座標參考系使用的是 WGS84 數據。json

平面

若是須要計算距離,就像在一個歐幾里德平面上,您能夠按照正常座標對的形式存儲位置數據並使用 2d索引。app

位置數據

若是您選擇球形表面來計算,您能夠選擇把位置數據存儲爲以下兩種格式之一:性能

GeoJSON對象

對 GeoJSON 的查詢老是基於球形表面。GeoJSON的默認座標參考系使用的是 WGS84 數據。優化

2.4 新版功能: 在版本2.4新引入了對GeoJSON的存儲和查詢支持。在版本2.4之前,全部的地理數據使用座標對的形式。spa

在 2.6 版更改: 支持更多GeoJSON類型:多點, 多線段, MultiPolygon, 幾何體集合。

MongoDB支持以下GeoJSON對象:

  • 單點

  • 線段

  • 多邊形

  • 多點

  • 多線段

  • MultiPolygon
  • 幾何體集合

普通座標對

MongoDB支持對使用 2dsphere 索引的 legacy coordinate pairs (普通座標對)數據進行球面計算,方式是把數據轉換成GeoJSON Point類型。

若是您選擇的是平面計算且使用 2d 索引,那麼您能夠把數據存儲爲僅 :term:`legacy coordinate pairs`格式。

查詢操做

MongoDB地理空間查詢操做容許您查詢:

包含

MongoDB能夠查詢被徹底包含於一個指定多邊形區域中的位置。包含查詢使用的是 $geoWithin 操做符。

兩種索引 2d 和 2dsphere 索引都支持包含查詢。在版本2.2.3以後,對於包含查詢,MongoDB再也不要求有索引。可是,這些索引能夠提高查詢性能。

交叉

MongoDB能夠查詢位置和一個指定幾何圖形的交叉。這些查詢僅能夠被用於查詢存儲在球形平面上的數據。這些查詢使用 $geoIntersects 操做符。

只有 2dsphere 索引才支持交叉。

鄰近

MongoDB能夠查詢和某個點最近的其餘點。鄰近查詢使用 $near 操做符。 $near 操做符要求有 2d 或者2dsphere 索引。

地理空間索引

MongoDB提供了以下的地理索引類型來支持地理查詢。

2dsphere

2dsphere 索引能夠支持以下特性:

  • 在球形平面上的計算

  • GeoJSON對象和對普通座標對的向後兼容。

  • 複合索引。這個複合索引能夠包含一個 2dsphere 索引字段以及一些按升序或降序創建的普通索引字段(做爲 2dsphere 索引的前綴或者後綴)。

2.4 新版功能: 在版本2.4以前``2dsphere`` 索引是不可用的。

2d

2d 索引支持以下特性:

  • 使用平面幾何的方式計算

  • 普通座標對(好比,在一個平面座標系中的點)

  • 做爲複合索引,額外索引一個鍵。方法是,把額外的一個鍵做爲 2d 索引鍵的後綴

地理空間索引和分片

您 不能 使用地理索引來做爲 shard key 索引。

您能夠在一個被分片的集合上建立並維護一個一個地理空間索引,使用的不能是分片鍵。

對於被分片的幾何,使用了 $near 操做的查詢是不被支持的。做爲替代,您可使用 geoNear 命令或者$geoNear 在聚合階段的時候。

您還可使用 $geoWithin 來查詢地理空間數據。

其它資源

如下頁面提供了關於地理空間索引和查詢的完整文檔

2dsphere 索引

MongoDB的 2dsphere 索引支持查詢在一個類地球的球面上進行幾何計算。 索引支持以GeoJSON對象或者普通座標對的方式存儲數據。

2d 索引

MongoDB的 2d 索引支持以普通座標對的方式存儲數據,用於MongoDB2.2版及之前

geoHaystack 索引

haystack索引是一個被特殊優化過的索引,用於返回小區域結果。對於那些使用球面幾何的查詢而言, 2dsphere 會是一個更好的選擇。

2d 索引原理

提供了對地理索引更深層次本質的闡釋。這份材料對於普通操做者不是必須的,可是對於正在排除障礙或者想要更深刻理解的用戶也許有點幫助。

參見

Geospatial Query Compatibility

 

二.示例

創建places集合,來存放地點, loc字段用來存放地區數據GeoJSON Point。

db.places.insert(
   {
      loc : { type: "Point", coordinates: [ -73.97, 40.77 ] },
      name: "Central Park",
      category : "Parks"
   }
)
 
db.places.insert(
   {
      loc : { type: "Point", coordinates: [ -73.88, 40.78 ] },
      name: "La Guardia Airport",
      category : "Airport"
   }
)

創建索引

db.places.ensureIndex( { loc : "2dsphere" } )

參數不是1或-1,爲2dsphere。還能夠創建組合索引。

db.places.ensureIndex( { loc : "2dsphere" , category : -1, name: 1 } )

3. 查詢

$geometry表示查詢的幾何圖片.

3.1 查詢多邊形範圍的值

type表示類型:polygon 多邊形

db.places.find( { loc :
                  { $geoWithin :
                    { $geometry :
                      { type : "Polygon" ,
                        coordinates : [ [
                                          [ 0 , 0 ] ,
                                          [ 3 , 6 ] ,
                                          [ 6 , 1 ] ,
                                          [ 0 , 0 ]
                                        ] ]
                } } } } )

3.2 查詢附近的值

使用$near來查詢附近的地點。

db.places.find( { loc :
                        { $near :
                          { $geometry :
                             { type : "Point" ,
                               coordinates : [ <longitude> , <latitude> ] } ,
                            $maxDistance : <distance in meters>
                     } } } )

3.3 查詢圓形內的值

查詢圓時,須要指定圓心, 半徑。

db.places.find( { loc :
                  { $geoWithin :
                    { $centerSphere :
                       [ [ -88 , 30 ] , 10 ]
                } } } )

[-88, 30] 爲經緯度, 10爲半徑。
地址:http://blog.csdn.net/yonggang7/article/details/28109463

 

二.項目中springMVC中是用mongoDb查詢範圍得點

  2.1創建索引

//deliver數據
deliver:{
"deliverArea": [
                {
                    "area": [
                        {
                            "district": "叢臺區",
                            "location": {
                                "lat": 36.613143702791,
                                "lng": 114.50521301419
                            },
                            "street": "朝陽路",
                            "street_number": "5號"
                        },
                        {
                            "district": "叢臺區",
                            "location": {
                                "lat": 36.612694686043,
                                "lng": 114.50516800908
                            },
                            "street": "朝陽路",
                            "street_number": "5號"
                        },
                        {
                            "district": "叢臺區",
                            "location": {
                                "lat": 36.612744657392,
                                "lng": 114.50573403138
                            },
                            "street": "朝陽路",
                            "street_number": "5號"
                        },
                        {
                            "district": "叢臺區",
                            "location": {
                                "lat": 36.61310669522,
                                "lng": 114.50577903649
                            },
                            "street": "朝陽路",
                            "street_number": "14號"
                        }
                    ]
                }
            ],
            "deliverId": "D011122"
}

 

db.deliver.ensureIndex({"deliverArea.area.location":"2dsphere"})

  2.2查詢命令

//mongoDB shell
db.deliver.aggregate([ { $geoNear: { near: { type:
"Point", coordinates: [ 114.495539 , 36.597626 ] }, distanceField: "deliverArea.area.location", maxDistance: 10, num: 5, spherical: true } } ])
//spingMvc 使用Aggregation 
Point location = new Point(114.495539 , 36.597626);
NearQuery query
= NearQuery.near(location).maxDistance(new Distance(distance, Metrics.MILES)).num(5).spherical(true);
Aggregation aggregation
= newAggregation( geoNear(query,"deliver") );
AggregationResults
<Deliver> results = mongoTemplate.aggregate(aggregation,"deliver",Deliver.class);
//spring 使用MongoOperations
Point location = new Point(-73.99171, 40.738868);
NearQuery query = NearQuery.near(location).maxDistance(new Distance(10, Metrics.MILES));

GeoResults<Restaurant> = operations.geoNear(query, Restaurant.class);

  使用MongoOperations  GeoResults 返回的deliver list數據中,deliver會被content包裝,要取出deliver數據需content中取。

  參考:http://docs.spring.io/spring-data/mongodb/docs/current/reference/html/

相關文章
相關標籤/搜索