Permalink
Fetching contributors…
Cannot retrieve contributors at this time
125 lines (94 sloc) 4.25 KB
======================
``2d`` Index Internals
======================
.. default-domain:: mongodb
.. contents:: On this page
:local:
:backlinks: none
:depth: 1
:class: singlecol
This document provides a more in-depth explanation of the internals of MongoDB's
``2d`` geospatial indexes. This material is not necessary for normal operations
or application development but may be useful for troubleshooting and for
further understanding.
.. _geospatial-indexes-geohash:
Calculation of Geohash Values for ``2d`` Indexes
------------------------------------------------
When you create a geospatial index on :term:`legacy coordinate pairs
<legacy coordinate pairs>`, MongoDB computes :term:`geohash` values
for the coordinate pairs within the specified :ref:`location range
<geospatial-indexes-range>` and then indexes the geohash values.
To calculate a geohash value, recursively divide a two-dimensional map into
quadrants. Then assign each quadrant a two-bit value. For example, a
two-bit representation of four quadrants would be:
.. code-block:: javascript
01 11
00 10
These two-bit values (``00``, ``01``, ``10``, and ``11``) represent each
of the quadrants and all points within each quadrant. For a geohash with
two bits of resolution, all points in the bottom left quadrant would
have a geohash of ``00``. The top left quadrant would have the geohash
of ``01``. The bottom right and top right would have a geohash of ``10``
and ``11``, respectively.
To provide additional precision, continue dividing each quadrant into
sub-quadrants. Each sub-quadrant would have the geohash value of the
containing quadrant concatenated with the value of the sub-quadrant. The
geohash for the upper-right quadrant is ``11``, and the geohash for the
sub-quadrants would be (clockwise from the top left): ``1101``,
``1111``, ``1110``, and ``1100``, respectively.
.. Commented out -- per Jesse's feedback, users don't control this. To
calculate a more precise geohash, continue dividing the sub-quadrant
and concatenate the two-bit identifier for each division. The more
"bits" in the hash identifier for a given point, the smaller possible
area that the hash can describe and the higher the resolution of the
geospatial index.
.. _geospatial-indexes-multi-location:
Multi-location Documents for ``2d`` Indexes
-------------------------------------------
.. note::
:doc:`2dsphere </core/2dsphere>` indexes can cover multiple geospatial fields
in a document, and can express lists of points using
:ref:`geojson-multipoint` embedded documents.
While ``2d`` geospatial indexes do not support more than one geospatial field
in a document, you can use a :ref:`multi-key index
<index-type-multi-key>` 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:
.. code-block:: javascript
db.places.save( {
locs : [ [ 55.5 , 42.3 ] ,
[ -74 , 44.74 ] ,
{ lng : 55.5 , lat : 42.3 } ]
} )
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 in
the following:
.. code-block:: javascript
db.places.createIndex( { "locs": "2d" } )
You may also model the location data as a field inside of an
embedded document. In this case, the document would contain a field
(e.g. ``addresses``) that holds an array of documents where each
document has a field (e.g. ``loc:``) that holds location
coordinates. For example:
.. code-block:: javascript
db.records.save( {
name : "John Smith",
addresses : [ {
context : "home" ,
loc : [ 55.5, 42.3 ]
} ,
{
context : "work",
loc : [ -74 , 44.74 ]
}
]
} )
You could then create the geospatial index on the ``addresses.loc`` field as
in the following example:
.. code-block:: javascript
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
:dbcommand:`geoNear` command.