2d 索引内部机制
本文档解释了 2 d 索引的内部结构。 本材料不是正常操作或应用程序开发所必需的,但可能有助于故障排除和进一步了解。
地理哈希(Geohash)值
在包含 legacy coordinate pairs 的字段上创建地理空间索引时,MongoDB 会计算指定 位置范围 内坐标对的 地理哈希(Geohash) 值,然后对 地理哈希(Geohash) 值编制索引。
为了计算地理哈希(Geohash)值,MongoDB会递归地将二维地图划分为多个象限。然后,它为每个象限分配一个两位值。 例如,四个象限的两位表示为:
01 11 00 10
这些两位值( 00
、 01
、 10
和11
)代表每个象限以及每个象限内的所有点。 每个象限都有相应的地理哈希(Geohash)值:
象限 | geohash |
---|---|
左下角 | 00 |
左上角 | 01 |
右下角 | 10 |
右上角 | 11 |
为了提供更高的精度,MongoDB 可以将每个象限划分为子象限。 每个子象限都有包含象限的地理哈希(Geohash)值与子象限的值。例如,右上象限的地理哈希(Geohash)为11
,子象限的地理哈希(Geohash)为(从左上角开始顺时针方向):
1101
1111
1110
1100
用于 2d 索引的多位置文档
虽然 2d 索引不支持在一份文档中存在多个位置字段,但您可以使用多键索引来索引单个文档中的多个坐标对。 例如,在以下文档中, locs
字段包含一个坐标对数组:
db.places.insertOne( { locs : [ [ 55.5 , 42.3 ], [ -74 , 44.74 ], { long : 55.5 , lat : 42.3 } ] } )
locs
数组中的值可以是:
数组,如
[ 55.5, 42.3 ]
中的数组。嵌入式文档,如
{ long : 55.5 , lat : 42.3 }
中。
要为locs
数组中的所有坐标对编制索引,请在locs
字段上创建 2d 索引:
db.places.createIndex( { "locs": "2d" } )
嵌入式多位置文档
您可以将位置数据存储为嵌入式文档内的字段。例如,您可以有一个嵌入式文档数组,其中每个嵌入式文档都有一个包含位置数据的字段。
在以下文档中, addresses
字段是嵌入式文档的数组。 嵌入式文档包含一个loc
字段,它是一个坐标对:
db.records.insertOne( { name : "John Smith", addresses : [ { context : "home" , loc : [ 55.5, 42.3 ] }, { context : "work", loc : [ -74 , 44.74 ] } ] } )
要为addresses
数组中的所有loc
值编制索引,请在addresses.loc
字段上创建 2d 索引:
db.records.createIndex( { "addresses.loc": "2d" } )