LBS-查找附近的人-mongodb實現(xiàn)-基礎(chǔ)知識

接下來我們開始介紹mongodb的解決方案蚕键。mongodb也是早些年“快的”的解決方案你画。

地理空間數(shù)據(jù)

在MongoDB中沟娱,可以將地理空間數(shù)據(jù)存儲為 GeoJSON對象傳統(tǒng)坐標(biāo)對 械巡。

GeoJSON對象

要計算類球體上的幾何體七婴,位置數(shù)據(jù)應(yīng)存儲為GeoJSON對象乳怎。

要指定GeoJSON數(shù)據(jù)彩郊,請使用嵌入式文檔:

  • type:指定GeoJSON對象類型
  • coordinates:指定對象的坐標(biāo)。
<field>: { type: <GeoJSON type> , coordinates: <coordinates> }

如:

location: {
      type: "Point",
      coordinates: [-73.856077, 40.848447]
}

GeoJSON對象在MongoDB地理空間查詢在球體上計算蚪缀,使用WGS84參考系統(tǒng)對GeoJSON對象進(jìn)行地理空間查詢秫逝。

傳統(tǒng)坐標(biāo)對

要計算歐幾里得平面上的距離,位置數(shù)據(jù)應(yīng)存儲為傳統(tǒng)坐標(biāo)對询枚,并使用2d索引违帆。將數(shù)據(jù)轉(zhuǎn)換為GeoJSON Point類型后,并通過2dsphere索引后傳統(tǒng)坐標(biāo)對也支持球面曲面計算金蜀。

要將數(shù)據(jù)指定為傳統(tǒng)坐標(biāo)對刷后,也有兩種數(shù)據(jù)格式可以使用,數(shù)組嵌入式文檔 渊抄。 官方推薦首先使用 數(shù)組尝胆。

數(shù)組方式(首選):

<field>:[<longitude>, <latitude>]

嵌入式文檔方式:

<field>:{<field1>:<longitude>, <field2>:<latitude>}
  • 有效經(jīng)度值介于-180和180。
  • 有效的緯度值介于-90和90护桦。

注意:為什么要說這個經(jīng)緯度的有效值呢含衔,因為mongodb不僅僅是對地球的經(jīng)緯系統(tǒng)支持,也支持其他的平面坐標(biāo)系。如果使用緯度和經(jīng)度坐標(biāo)必須使用 longitude(經(jīng)度)在前贪染,latitude(緯度)在后的順序缓呛。

地理空間索引

在MongoDB中,地理數(shù)據(jù)相關(guān)的索引有兩種 2dsphere2d杭隙。地球狀球體計算幾何的查詢應(yīng)使用 2dsphere 索引哟绊。 2d 索引在二維平面上使用存儲為點(diǎn)的數(shù)據(jù)的索引。該 2d 索引適用于MongoDB 2.2及更早版本中使用的傳統(tǒng)坐標(biāo)對寺渗。

當(dāng)然通過將數(shù)據(jù)轉(zhuǎn)換為GeoJSON Point類型匿情,MongoDB通過2dsphere索引支持傳統(tǒng)坐標(biāo)對上的球面曲面計算。所以 GeoJSON對象傳統(tǒng)坐標(biāo)對 更加強(qiáng)大復(fù)雜信殊,但是 傳統(tǒng)坐標(biāo)對 也是支持 2dsphere

兩種索引的方式雖然不同炬称,不過,只要坐標(biāo)跨度不太大(比如幾百幾千公里)涡拘,這兩個索引計算出的距離相差幾乎可以忽略不計玲躯。

  1. 2dsphere

2dsphere索引支持在地球球上計算幾何的查詢。

db.collection.createIndex({ <location field>: "2dsphere" })
  1. 2d

2d索引支持在二維平面上計算幾何的查詢 鳄乏。盡管索引可以支持 $nearSphere 在球體上計算的查詢跷车,但如果可能的話,請使用 2dsphere 索引進(jìn)行球形查詢橱野。

db.collection.createIndex({ <location field> : "2d" })

其中 <location field> 的值是 GeoJSON對象傳統(tǒng)坐標(biāo)對 的字段朽缴。

地理空間查詢運(yùn)算符

MongoDB提供了以下地理空間查詢操作符:

名稱 描述
$geoIntersects 選擇與GeoJSON幾何體相交的幾何體,2dsphere索引支持
$geoWithin 選擇邊界GeoJSON幾何內(nèi)的幾何水援,2dsphere和2D索引支持
$near 返回靠近點(diǎn)的地理空間對象密强。需要一個地理空間索引,2dsphere和2d索引支持
$nearSphere 返回球體上某個點(diǎn)附近的地理空間物體蜗元。需要一個地理空間索引或渤,dsphere和2d索引支持

其中 $geoNear 包含 $match,$sort和$limit參數(shù)奕扣。輸出文件包含一個額外的距離字段薪鹦,并可包含位置標(biāo)識符字段。

下表列出了每個地理空間操作使用的地理空間查詢運(yùn)算符:

方法 坐標(biāo) 說明
$near(GeoJSON質(zhì)心點(diǎn)在這一行和下面一行惯豆,2dsphere) 球形 另請參閱$nearSphere運(yùn)算符池磁,它在與GeoJSON和2dsphere索引一起使用時提供相同的功能。
$near(傳統(tǒng)坐標(biāo)楷兽,2d) 平面
$nearSphere(GeoJSON框仔,2dsphere) 球形 提供與$near使用GeoJSON和2dsphere相同的功能。對于球形查詢拄养,最好使用 $nearSphere明確指定名稱中的球形查詢而不是$near
$nearSphere(傳統(tǒng)坐標(biāo)离斩,2d) 球形 改為使用GeoJSON點(diǎn)银舱。
$geoWithin:{ $geometry:...} 球形
$geoWithin:{ $box:...} 平面
$geoWithin:{ $polygon:...} 平面
$geoWithin:{ $center:...} 平面
$geoWithin:{ $centerSphere:...} 球形
$geoIntersects 球形
$geoNear(2dsphere) 球形
$geoNear(2d) 平面

示例

GeoJSON對象數(shù)據(jù)

創(chuàng)建集合-插入數(shù)據(jù)-建立索引

#創(chuàng)建集合
db.createCollection("places")
#插入數(shù)據(jù)
db.places.insert({
    name: "Central Park",
   location: { type: "Point", coordinates: [ -73.97, 40.77 ] },
   category: "Parks"
} );
db.places.insert({
   name: "Sara D. Roosevelt Park",
   location: { type: "Point", coordinates: [ -73.9928, 40.7193 ] },
   category: "Parks"
} );
db.places.insert({
   name: "Polo Grounds",
   location: { type: "Point", coordinates: [ -73.9375, 40.8303 ] },
   category: "Stadiums"
} );
#在location字段上創(chuàng)建索引
db.places.createIndex( { location: "2dsphere" } )

以下查詢使用$near操作返回距離指定GeoJSON至少1000米且最遠(yuǎn)5000米的數(shù)據(jù),并按從最近到最遠(yuǎn)的順序排序:

db.places.find(
   {
     location:
       { $near:
          {
            $geometry: { type: "Point",  coordinates: [ -73.9667, 40.78 ] },
            $minDistance: 1000,
            $maxDistance: 5000
          }
       }
   }
)

以下查詢使用$geoNear命令查詢并過濾 { category: "Parks" } 相匹配的數(shù)據(jù)跛梗,按照距離指定的GeoJSON最近的順序排序

db.runCommand(
   {
     geoNear: "places",
     near: { type: "Point", coordinates: [ -73.9667, 40.78 ] },
     spherical: true,
     query: { category: "Parks" }
   }
)

傳統(tǒng)坐標(biāo)對數(shù)據(jù)

創(chuàng)建集合-插入數(shù)據(jù)-建立索引

db.createCollection("location")
db.location.save( {_id: "A", position: [0.1, -0.1]} )
db.location.save( {_id: "B", position: [1.0, 1.0]} )
db.location.save( {_id: "C", position: [0.5, 0.5]} )
db.location.save( {_id: "D", position: [-0.5, -0.5]} )
db.location.ensureIndex( {position: "2d"} )

查詢point(0,0),半徑0.7附近的點(diǎn)

db.location.find( {position: { $near: [0,0], $maxDistance: 0.7  } } )

查詢[0.25, 0.25], [1.0,1.0]區(qū)域附近的點(diǎn)

db.location.find( {position: { $geoWithin: { $box: [ [0.25, 0.25], [1.0,1.0] ] } } } )

參考 mongodb官方文檔

到此mongodb地理數(shù)據(jù)支持的基礎(chǔ)知識已經(jīng)介紹完寻馏,請看下篇實戰(zhàn)篇,我們還是會生成600w調(diào)數(shù)據(jù)mongodb方案進(jìn)行測試核偿。

文章同步發(fā)布在博客诚欠,LBS-查找附近的人-mongodb實現(xiàn)-基礎(chǔ)知識

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市漾岳,隨后出現(xiàn)的幾起案子轰绵,更是在濱河造成了極大的恐慌,老刑警劉巖尼荆,帶你破解...
    沈念sama閱讀 222,183評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件左腔,死亡現(xiàn)場離奇詭異,居然都是意外死亡捅儒,警方通過查閱死者的電腦和手機(jī)液样,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,850評論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來巧还,“玉大人鞭莽,你說我怎么就攤上這事◆锏唬” “怎么了澎怒?”我有些...
    開封第一講書人閱讀 168,766評論 0 361
  • 文/不壞的土叔 我叫張陵,是天一觀的道長阶牍。 經(jīng)常有香客問我丹拯,道長,這世上最難降的妖魔是什么荸恕? 我笑而不...
    開封第一講書人閱讀 59,854評論 1 299
  • 正文 為了忘掉前任,我火速辦了婚禮死相,結(jié)果婚禮上融求,老公的妹妹穿的比我還像新娘。我一直安慰自己算撮,他們只是感情好生宛,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,871評論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著肮柜,像睡著了一般陷舅。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上审洞,一...
    開封第一講書人閱讀 52,457評論 1 311
  • 那天莱睁,我揣著相機(jī)與錄音待讳,去河邊找鬼。 笑死仰剿,一個胖子當(dāng)著我的面吹牛创淡,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播南吮,決...
    沈念sama閱讀 40,999評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼琳彩,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了部凑?” 一聲冷哼從身側(cè)響起露乏,我...
    開封第一講書人閱讀 39,914評論 0 277
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎涂邀,沒想到半個月后衡创,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體洋侨,經(jīng)...
    沈念sama閱讀 46,465評論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,543評論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了即硼。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,675評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡循捺,死狀恐怖留量,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情赡勘,我是刑警寧澤嫂便,帶...
    沈念sama閱讀 36,354評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站闸与,受9級特大地震影響毙替,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜践樱,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,029評論 3 335
  • 文/蒙蒙 一厂画、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧拷邢,春花似錦袱院、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,514評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至环肘,卻和暖如春欲虚,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背悔雹。 一陣腳步聲響...
    開封第一講書人閱讀 33,616評論 1 274
  • 我被黑心中介騙來泰國打工复哆, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留欣喧,地道東北人。 一個月前我還...
    沈念sama閱讀 49,091評論 3 378
  • 正文 我出身青樓寂恬,卻偏偏與公主長得像续誉,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子初肉,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,685評論 2 360

推薦閱讀更多精彩內(nèi)容