2d Index Internals

This document provides a more in-depth explanation of the internals of MongoDB’s2d geospatial indexes. This material is not necessary for normal operationsor application development but may be useful for troubleshooting and forfurther understanding.

Calculation of Geohash Values for 2d Indexes

When you create a geospatial index on legacy coordinate pairs, MongoDB computes geohash valuesfor the coordinate pairs within the specified location range and then indexes the geohash values.

To calculate a geohash value, recursively divide a two-dimensional map intoquadrants. Then assign each quadrant a two-bit value. For example, atwo-bit representation of four quadrants would be:

  1. 01 11
  2.  
  3. 00 10

These two-bit values (00, 01, 10, and 11) represent eachof the quadrants and all points within each quadrant. For a geohash withtwo bits of resolution, all points in the bottom left quadrant wouldhave a geohash of 00. The top left quadrant would have the geohashof 01. The bottom right and top right would have a geohash of 10and 11, respectively.

To provide additional precision, continue dividing each quadrant intosub-quadrants. Each sub-quadrant would have the geohash value of thecontaining quadrant concatenated with the value of the sub-quadrant. Thegeohash for the upper-right quadrant is 11, and the geohash for thesub-quadrants would be (clockwise from the top left): 1101,1111, 1110, and 1100, respectively.

Multi-location Documents for 2d Indexes

Note

2dsphere indexes can cover multiple geospatial fieldsin a document, and can express lists of points usingMultiPoint embedded documents.

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

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

The values of the array may be either arrays, as in [ 55.5, 42.3 ],or embedded documents, as in { lng : 55.5 , lat : 42.3 }.

You could then create a geospatial index on the locs field, as inthe following:

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

You may also model the location data as a field inside of anembedded document. In this case, the document would contain a field(e.g. addresses) that holds an array of documents where eachdocument has a field (e.g. loc:) that holds locationcoordinates. For example:

  1. db.records.save( {
  2. name : "John Smith",
  3. addresses : [ {
  4. context : "home" ,
  5. loc : [ 55.5, 42.3 ]
  6. } ,
  7. {
  8. context : "work",
  9. loc : [ -74 , 44.74 ]
  10. }
  11. ]
  12. } )

You could then create the geospatial index on the addresses.loc field asin the following example:

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