MongoDB的geo索引是其一大特色,本文从原理层面讲述geo索引中的2d索引的实现。
2d 索引的创建与使用
通过 db.coll.createIndex({"lag":"2d"}, {"bits":int}))
来创建一个2d索引,索引的精度通过bits来指定,bits越大,索引的精度就越高。更大的bits带来的插入的overhead可以忽略不计。
通过
db.runCommand({ geoNear: tableName, maxDistance: 0.0001567855942887398, distanceMultiplier: 6378137.0, num: 30, near: [ 113.8679388183982, 22.58905429302385 ], spherical: true|false})
来查询一个索引,其中spherical:true|false 表示应该如何理解创建的2d索引,false表示将索引理解为平面2d索引,true表示将索引理解为球面经纬度索引。这一点比较有意思,一个2d索引可以表达两种含义,而不同的含义是在查询时被理解的,而不是在索引创建时。
2d索引的理论
Mongodb 使用一种叫做Geohash的技术来构建2d索引,但是Mongodb的Geohash并没有使用国际通用的每一层级32个grid的Geohash描述方式(见wiki geohash)。而是使用平面四叉树的形式。
如下图:
很显然的,一个2bits的精度能把平面分为4个grid,一个4bits的精度能把平面分为16个grid。2d索引的默认精度是长宽各为26,索引把地球分为(2^26)(2^26)块,每一块的边长估算为
2*PI*6371000/(1<<26) =