|
| 1 | +============== |
| 2 | +``2d`` Indexes |
| 3 | +============== |
| 4 | + |
| 5 | +.. default-domain:: mongodb |
| 6 | + |
| 7 | +Use a ``2d`` index for data stored as points on a two-dimensional plane. The |
| 8 | +``2d`` index is intended for legacy coordinate pairs used in MongoDB 2.2 |
| 9 | +and earlier. |
| 10 | + |
| 11 | +Use a ``2d`` index if: |
| 12 | + |
| 13 | +- your database has legacy location data from MongoDB 2.2 or earlier, *and* |
| 14 | + |
| 15 | +- you do not intend to store any location data as :term:`GeoJSON` objects. |
| 16 | + |
| 17 | +Do not use a ``2d`` index if your location data includes GeoJSON objects. To |
| 18 | +index on both legacy coordinate pairs *and* GeoJSON objects, use a |
| 19 | +:doc:`2dsphere index </applications/2dsphere>`. |
| 20 | + |
| 21 | +The ``2d`` index supports calculations on a flat, Euclidean plane. The |
| 22 | +``2d`` index also supports *distance-only* calculations on a sphere, but |
| 23 | +for *geometric* calculations on a sphere, store data as GeoJSON objects |
| 24 | +and use the ``2dsphere`` index type. |
| 25 | + |
| 26 | +A ``2d`` index can reference two fields. The first must be the location |
| 27 | +field. A ``2d`` compound index constructs queries that select first on |
| 28 | +the location field and second on the additional field. If the location |
| 29 | +criteria selects a large number of documents, the additional criteria |
| 30 | +only filters the result set. The additional criteria *does not* result |
| 31 | +in a more targeted query. |
| 32 | + |
| 33 | +MongoDB allows one ``2d`` index per collection. |
| 34 | + |
| 35 | +.. important:: You cannot use a ``2d`` index as a shard key when |
| 36 | + sharding a collection. However, you can create and maintain a |
| 37 | + geospatial index on a sharded collection by using a different field |
| 38 | + as the shard key. |
| 39 | + |
| 40 | +.. _geospatial-indexes-store-grid-coordinates: |
| 41 | + |
| 42 | +Store Points on a 2D Plane |
| 43 | +-------------------------- |
| 44 | + |
| 45 | +To store location data as legacy coordinate pairs, use either an array |
| 46 | +(preferred): |
| 47 | + |
| 48 | +.. code-block:: javascript |
| 49 | + |
| 50 | + loc : [ <long> , <lat> ] |
| 51 | + |
| 52 | +Or an embedded document: |
| 53 | + |
| 54 | +.. code-block:: javascript |
| 55 | + |
| 56 | + loc : { long : <long> , lat : <lat> } |
| 57 | + |
| 58 | +Arrays are preferred as certain languages do not guarantee associative |
| 59 | +map ordering. |
| 60 | + |
| 61 | +Whether as an array or document, if you use longitude and latitude, |
| 62 | +store coordinates in this order: **longitude, latitude**. |
| 63 | + |
| 64 | +.. _geospatial-create-2d-index: |
| 65 | + |
| 66 | +Create a ``2d`` Index |
| 67 | +--------------------- |
| 68 | + |
| 69 | +To build a geospatial ``2d`` index, use the :method:`ensureIndex() |
| 70 | +<db.collection.ensureIndex()>` method and specify ``2d``. Use the |
| 71 | +following syntax: |
| 72 | + |
| 73 | +.. code-block:: javascript |
| 74 | + |
| 75 | + db.<collection>.ensureIndex( { <location field> : "2d" , <additional field> : <value> } , |
| 76 | + { <index-specification options> } ) |
| 77 | + |
| 78 | +The ``2d`` index uses the following optional index-specification |
| 79 | +options: |
| 80 | + |
| 81 | +.. code-block:: javascript |
| 82 | + |
| 83 | + { min : <lower bound> , max : <upper bound> , |
| 84 | + bits : <bit precision> } |
| 85 | + |
| 86 | +.. _geospatial-indexes-range: |
| 87 | + |
| 88 | +Define Location Range for a ``2d`` Index |
| 89 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 90 | + |
| 91 | +By default, a ``2d`` index assumes longitude and latitude and has boundaries |
| 92 | +of -180 inclusive and 180 non-inclusive (i.e. ``[ -180 , 180 ]``). If |
| 93 | +documents contain coordinate data outside of the specified range, |
| 94 | +MongoDB returns an error. |
| 95 | + |
| 96 | +.. important:: The default boundaries allow applications to insert |
| 97 | + documents with invalid latitudes greater than 90 or less than -90. |
| 98 | + The behavior of geospatial queries with such invalid points is not |
| 99 | + defined. |
| 100 | + |
| 101 | +On ``2d`` indexes you can change the location range. |
| 102 | + |
| 103 | +You can build a ``2d`` geospatial index with a location range other than |
| 104 | +the default. Use the ``min`` and ``max`` options when creating the |
| 105 | +index. Use the following syntax: |
| 106 | + |
| 107 | +.. code-block:: javascript |
| 108 | + |
| 109 | + db.collection.ensureIndex( { <location field> : "2d" } , |
| 110 | + { min : <lower bound> , max : <upper bound> } ) |
| 111 | + |
| 112 | +.. _geospatial-indexes-precision: |
| 113 | + |
| 114 | +Define Location Precision for a ``2d`` Index |
| 115 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 116 | + |
| 117 | +By default, a ``2d`` index on legacy coordinate pairs uses 26 bits of |
| 118 | +precision, which is roughly equivalent to 2 feet or 60 centimeters of |
| 119 | +precision using the default range of -180 to 180. Precision is measured |
| 120 | +by the size in bits of the :term:`geohash` values used to store location |
| 121 | +data. You can configure geospatial indexes with up to 32 bits of |
| 122 | +precision. |
| 123 | + |
| 124 | +Index precision does not affect query accuracy. The actual grid coordinates |
| 125 | +are always used in the final query processing. Advantages to lower |
| 126 | +precision are a lower processing overhead for insert operations and use |
| 127 | +of less space. An advantage to higher precision is that queries scan |
| 128 | +smaller portions of the index to return results. |
| 129 | + |
| 130 | +To configure a location precision other than the default, use the |
| 131 | +``bits`` option when creating the index. Use following syntax: |
| 132 | + |
| 133 | +.. code-block:: javascript |
| 134 | + |
| 135 | + db.<collection>.ensureIndex( {<location field> : "<index type>"} , |
| 136 | + { bits : <bit precision> } ) |
| 137 | + |
| 138 | +For information on the internals of geohash values, see |
| 139 | +:ref:`geospatial-indexes-geohash`. |
| 140 | + |
| 141 | +Query a ``2d`` Index |
| 142 | +-------------------- |
| 143 | + |
| 144 | +The following sections describe queries supported by the ``2d`` index. |
| 145 | +For an overview of recommended geospatial queries, see |
| 146 | +:doc:`/reference/geospatial-queries`. |
| 147 | + |
| 148 | +Points within a Shape Defined on a Flat Surface |
| 149 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 150 | + |
| 151 | +To select all legacy coordinate pairs found within a given shape on a flat |
| 152 | +surface, use the :operator:`$geoWithin` operator along with a shape |
| 153 | +operator. Use the following syntax: |
| 154 | + |
| 155 | +.. code-block:: javascript |
| 156 | + |
| 157 | + db.<collection>.find( { <location field> : |
| 158 | + { $geoWithin : |
| 159 | + { $box|$polygon|$center : <coordinates> |
| 160 | + } } } ) |
| 161 | + |
| 162 | +The following queries for documents within a rectangle defined by ``[ 0 |
| 163 | +, 0 ]`` at the bottom left corner and by ``[ 100 , 100 ]`` at the top |
| 164 | +right corner. |
| 165 | + |
| 166 | +.. code-block:: javascript |
| 167 | + |
| 168 | + db.places.find( { loc : { $geoWithin : { $box : |
| 169 | + [ [ 0 , 0 ] , |
| 170 | + [ 100 , 100 ] ] } } } ) |
| 171 | + |
| 172 | +The following queries for documents that are within the circle centered |
| 173 | +on ``[ -74 , 40.74 ]`` and with a radius of ``10``: |
| 174 | + |
| 175 | +.. code-block:: javascript |
| 176 | + |
| 177 | + db.places.find( { loc: { $geoWithin : |
| 178 | + { $center : [ [-74, 40.74], 10 ] } |
| 179 | + } } ) |
| 180 | + |
| 181 | +For syntax and examples for each shape, see the following: |
| 182 | + |
| 183 | + - :operator:`$box` |
| 184 | + |
| 185 | + - :operator:`$polygon` |
| 186 | + |
| 187 | + - :operator:`$center` (defines a circle) |
| 188 | + |
| 189 | +Points within a Circle Defined on a Sphere |
| 190 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 191 | + |
| 192 | +MongoDB supports rudimentary spherical queries on flat ``2d`` indexes for |
| 193 | +legacy reasons. In general, spherical calculations should use a ``2dsphere`` |
| 194 | +index, as described in :doc:`/applications/2dsphere`. |
| 195 | + |
| 196 | +To query for legacy coordinate pairs in a "spherical cap" on a sphere, |
| 197 | +use :operator:`$geoWithin` with the :operator:`$centerSphere` operator. |
| 198 | +Specify an array that contains: |
| 199 | + |
| 200 | +- The grid coordinates of the circle's center point |
| 201 | + |
| 202 | +- The circle's radius measured in radians. To calculate radians, see |
| 203 | + :doc:`/tutorial/calculate-distances-using-spherical-geometry-with-2d-geospatial-indexes`. |
| 204 | + |
| 205 | +Use the following syntax: |
| 206 | + |
| 207 | +.. code-block:: javascript |
| 208 | + |
| 209 | + db.<collection>.find( { <location field> : |
| 210 | + { $geoWithin : |
| 211 | + { $centerSphere : [ [ <x>, <y> ] , <radius> ] } |
| 212 | + } } ) |
| 213 | + |
| 214 | +The following example query returns all documents within a 10-mile |
| 215 | +radius of longitude ``88 W`` and latitude ``30 N``. The example converts |
| 216 | +distance to radians by dividing distance by the approximate radius of |
| 217 | +the earth, 3959 miles: |
| 218 | + |
| 219 | +.. code-block:: javascript |
| 220 | + |
| 221 | + db.<collection>.find( { loc : { $geoWithin : |
| 222 | + { $centerSphere : |
| 223 | + [ [ 88 , 30 ] , 10 / 3959 ] |
| 224 | + } } } ) |
| 225 | + |
| 226 | +Proximity to a Point on a Flat Surface |
| 227 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 228 | + |
| 229 | +Proximity queries return the 100 legacy coordinate pairs closest to the |
| 230 | +defined point and sort the results by distance. Use either the |
| 231 | +:operator:`$near` operator or :dbcommand:`geoNear` command. Both require |
| 232 | +a ``2d`` index. |
| 233 | + |
| 234 | +The :operator:`$near` operator uses the following syntax: |
| 235 | + |
| 236 | +.. code-block:: javascript |
| 237 | + |
| 238 | + db.<collection>.find( { <location field> : |
| 239 | + { $near : [ <x> , <y> ] |
| 240 | + } } ) |
| 241 | + |
| 242 | +For examples, see :operator:`$near`. |
| 243 | + |
| 244 | +The :dbcommand:`geoNear` command uses the following syntax: |
| 245 | + |
| 246 | +.. code-block:: javascript |
| 247 | + |
| 248 | + db.runCommand( { geoNear: <collection>, near: [ <x> , <y> ] } ) |
| 249 | + |
| 250 | +The :dbcommand:`geoNear` command offers more options and returns more |
| 251 | +information than does the :operator:`$near` operator. To run the |
| 252 | +command, see :dbcommand:`geoNear`. |
| 253 | + |
| 254 | +.. index:: geospatial queries |
| 255 | +.. index:: geospatial queries; exact |
| 256 | +.. _geospatial-indexes-exact-match: |
| 257 | + |
| 258 | +Exact Matches on a Flat Surface |
| 259 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 260 | + |
| 261 | +You can use the :method:`db.collection.find()` method to query for an |
| 262 | +exact match on a location. These queries use the following syntax: |
| 263 | + |
| 264 | +.. code-block:: javascript |
| 265 | + |
| 266 | + db.<collection>.find( { <location field>: [ <x> , <y> ] } ) |
| 267 | + |
| 268 | +This query will return any documents with the value of ``[ <x> , <y> ]``. |
0 commit comments