翻译或纠错本页面

2d 索引原理

这篇文档对MongoDB的 2d 地理索引提供了更深层次的内在机制解释。这份材料对于普通操作或者应用开发并不是必要的,但是对于故障排除或者想要更多了解的用户也许有用。

2d 索引计算Geohash值

当您基于 普通坐标 创建索引,MongoDB会在给定 位置范围 内的为坐标计算 geohash 并索引该geohash值。

为了计算geohash, 需要迭代地把一个二维区域划分为四个象限。然后,给每个象限赋予一个2-bit值。例如,四个象限的2-bit值如下:

01  11

00  10

这些2-bit值 (00, 01, 10, 11) 分别代表了一个象限和在这个象限内的所有点。求解时,所有在左下角象限的点将会拥有geohash 00. 左上角象限的点的geohash会是 01 .依此类推,右下角和右上角的geohash分别是 1011

为了能更精确的索引,继续把每个象限划分为子象限。 每个子象限也一样会有geohash, 由父象限的geohash和子象限的geohash拼接在一起。右上角象限的geohash是 11 ,所以它的子象限的geohash将是(从左上开始,顺时针方向) 1101 , 1111 , 1110 , 和 1100

多个位置数据的文档的 2d 索引

注解

2dsphere indexes can cover multiple geospatial fields in a document, and can express lists of points using MultiPoint embedded documents.

While 2d geospatial indexes do not support more than one geospatial field in a document, you can use a multi-key index to index multiple coordinate pairs in a single document. In the simplest example you may have a field (e.g. locs) that holds an array of coordinates, as in the following example:

db.places.save( {
  locs : [ [ 55.5 , 42.3 ] ,
           [ -74 , 44.74 ] ,
           { lng : 55.5 , lat : 42.3 } ]
} )

数组中的元素坐标, 可以是数组形式, 如

您可以在 locs 键上创建一个地理索引如下:

db.places.createIndex( { "locs": "2d" } )

也许,您把位置数据建模为子文档中的一个键。在这种情况下,文档中应该有一个键(例如 addresses ) 存储了子文档数组, 其中每篇子文档都有一个键(例如 loc: )存储着位置坐标。如下:

db.records.save( {
  name : "John Smith",
  addresses : [ {
                 context : "home" ,
                 loc : [ 55.5, 42.3 ]
                } ,
                {
                 context : "work",
                 loc : [ -74 , 44.74 ]
                }
              ]
} )

那么, 您可以在 addresses.loc 键上创建地理索引,如下:

db.records.createIndex( { "addresses.loc": "2d" } )

To include the location field with the distance field in multi-location document queries, specify includeLocs: true in the geoNear command.