圖解 MongoDB 地理位置索引的實(shí)現(xiàn)原理(轉(zhuǎn))

          地理位置索引支持是MongoDB的一大亮點(diǎn),這也是全球最流行的LBS服務(wù)foursquare 選擇MongoDB的原因之一。我們知道,通常的數(shù)據(jù)庫(kù)索引結(jié)構(gòu)是B+ Tree,如何將地理位置轉(zhuǎn)化為可建立B+Tree的形式,下文將為你描述。

          首先假設(shè)我們將需要索引的整個(gè)地圖分成16×16的方格,如下圖(左下角為坐標(biāo)0,0 右上角為坐標(biāo)16,16):

           

          單純的[x,y]的數(shù)據(jù)是無(wú)法建立索引的,所以MongoDB在建立索引的時(shí)候,會(huì)根據(jù)相應(yīng)字段的坐標(biāo)計(jì)算一個(gè)可以用來(lái)做索引的hash值,這個(gè)值叫做geohash,下面我們以地圖上坐標(biāo)為[4,6]的點(diǎn)(圖中紅叉位置)為例。

          我們第一步將整個(gè)地圖分成等大小的四塊,如下圖:



          劃分成四塊后我們可以定義這四塊的值,如下(左下為00,左上為01,右下為10,右上為11):

          01 11
          00 10

          這樣[4,6]點(diǎn)的geohash值目前為 00

          然后再將四個(gè)小塊每一塊進(jìn)行切割,如下:



          這時(shí)[4,6]點(diǎn)位于右上區(qū)域,右上的值為11,這樣[4,6]點(diǎn)的geohash值變?yōu)椋?011

          繼續(xù)往下做兩次切分:




          最終得到[4,6]點(diǎn)的geohash值為:00110100

          這樣我們用這個(gè)值來(lái)做索引,則地圖上點(diǎn)相近的點(diǎn)就可以轉(zhuǎn)化成有相同前綴的geohash值了。

          我們可以看到,這個(gè)geohash值的精確度是與劃分地圖的次數(shù)成正比的,上例對(duì)地圖劃分了四次。而MongoDB默認(rèn)是進(jìn)行26次劃分,這個(gè)值在建立索引時(shí)是可控的。具體建立二維地理位置索引的命令如下:

          db.map.ensureIndex({point : "2d"}, {min : 0, max : 16, bits : 4})

          其中的bits參數(shù)就是劃分幾次,默認(rèn)為26次。










           

          posted on 2011-11-25 17:19 胡鵬 閱讀(579) 評(píng)論(0)  編輯  收藏


          只有注冊(cè)用戶(hù)登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           

          導(dǎo)航

          <2011年11月>
          303112345
          6789101112
          13141516171819
          20212223242526
          27282930123
          45678910

          統(tǒng)計(jì)

          常用鏈接

          留言簿(3)

          隨筆分類(lèi)

          隨筆檔案

          agile

          搜索

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

          主站蜘蛛池模板: 尤溪县| 嘉峪关市| 泰安市| 桑日县| 军事| 淅川县| 同仁县| 洪雅县| 自治县| 团风县| 宁远县| 丰镇市| 康保县| 若羌县| 自贡市| 吉安县| 大兴区| 方城县| 邯郸市| 泰安市| 镇宁| 乌拉特后旗| 砀山县| 永川市| 定西市| 阿鲁科尔沁旗| 砚山县| 库伦旗| 赤城县| 梅河口市| 阳春市| 阜新| 西林县| 安阳市| 宝丰县| 连山| 景洪市| 明溪县| 城市| 蒙城县| 精河县|