diff --git a/draft/applications/geospatial-indexes.txt b/draft/applications/geospatial-indexes.txt index 96a19c4c096..824dc3e7635 100644 --- a/draft/applications/geospatial-indexes.txt +++ b/draft/applications/geospatial-indexes.txt @@ -4,12 +4,12 @@ Using Geospatial Data .. default-domain:: mongodb -MongoDB provides rich location aware queries that return documents -based on location with a special geospatial index type. This document -introduces geospatial data modeling, indexing operations, and provides -example queries using the :ref:`geospatial query operators -`. For more information about -geospatial indexes and operations see the :doc:`/core/geospatial-indexes` document. +MongoDB provides functionality to store and query geospatial data with +specialized operators. This document introduces geospatial data +modeling, indexing operations, and provides example queries using the +:ref:`geospatial query operators `. For +more information about geospatial indexes and operations see the +:doc:`/core/geospatial-indexes` document. .. _geospatial-coordinates: @@ -24,22 +24,29 @@ geospatial indexes and operations see the :doc:`/core/geospatial-indexes` docume Queries ------- -MongoDB provides special :ref:`geospatial query operators -` for performing queries on location data -inside the normal :func:`find() ` method. The -:dbcommand:`geoNear` command also returns results using geospatial -indexes, but also includes additional geospatial information in the -return documents. +There are two operators to query geospatial data in MongoDB, +the general :func:`find() ` method and the +specialized :dbcommand:`geoNear` command. + +You may query geospatial data using the :func:`find() +`, this is the same as querying other types of +data in MongoDB. Another way is to use the :dbcommand:`geoNear` +command, this is the same as running database commands. + +The :dbcommand:`geoNear` command is more specialized as it returns +detailed geospatial information for each result such as distance and +overall query performance. This provides addtional benefits when only +working with geospatial data. + +.. TODO does it make sense to have this here?? .. note:: - By default all MongoDB assumes that coordinate systems are on flat - planes and all distances calculated by the :dbcommand:`geoNear` use - the Pythagorean distance formula. + By default, MongoDB calculates distances using flat geometry. - MongoDB can also calculate and return accurate results for - locations in a :ref:`spherical ` - coordinate system, using :ref:`spherical query operations `. + MongoDB can also calculate distances based on :ref:`spherical + geometry ` by using + :ref:`spherical query operators `. .. index:: geospatial queries; exact @@ -49,25 +56,18 @@ Exact ~~~~~ You can use the :func:`find() ` method to query -for an exact match on a location. These queries take the -following prototypical form: +for an exact match on a location. These queries have the prototypical +form: .. code-block:: javascript db.collection.find( { : [ x, y ] } ) -This query will return any document that where the value of ``[ x, y -]`` is *exactly* the same as the one specified in the query. To return -all documents in the ``places`` collection with values in the ``loc`` -field that are exactly ``[ -74, 40.74 ]``, consider the following example: +This query will return any documents with the value of ``[ x, y ]``. -.. code-block:: javascript - - db.places.find( { "loc": [ -74, 40.74 ] } ) - -Exact geospatial queries only have applicability for a limited selection of -cases, :ref:`proximity ` and :ref:`bounded -` provide more useful results. +Exact geospatial queries have applicability for a limited selection of +cases, the :ref:`proximity ` method and :ref:`bounded +` method provide more useful results. .. index:: geospatial queries; proximity .. _geospatial-query-near: @@ -76,32 +76,36 @@ cases, :ref:`proximity ` and :ref:`bounded Proximity ~~~~~~~~~ -Proximity queries take a coordinate pair and return a result set of -documents from the geospatial index that are close to the query -coordinates, sorted by distance. You can use the :operator:`$near` -operator in a :func:`find() ` query to return -the 100 closest points to a coordinate (e.g. ``[ x, y ]``.) These -queries have the following prototype form: +To find all documents that are within a proximity of a point, use the +:operator:`$near` operator with the :func:`find() +` method. By default, the :operator:`$near` will +return 100 points sorted by distance. + +The prototype form for the :operator:`$near` operator is: .. code-block:: javascript db.collection.find( { : { $near: [ x, y ] } } ) -Consider the following example query: +For example, .. code-block:: javascript - db.places.find( { loc: { $near: [ -74, 40.74 ] } } ) + db.places.find( { loc: {$near: [-70,40] } }) -This operation will return documents from a collection named -``places`` that has a geospatial index on the ``loc`` field, near the -coordinates ``[ -74, 40.74 ]``. +and the output is: -In addition to :operator:`near`, the :dbcommand:`geoNear` command -provides equivalent functionality. :dbcommand:`geoNear` adds -additional options and returns more information for each -document found. In its most simple form, the :dbcommand:`geoNear` -command has the following prototypical form: +.. code-block:: javascript + + { "_id" : ObjectId(" ... "), "loc" : [ -73, 40 ] } + +The :dbcommand:`geoNear` command provides the equivalent functionality +to the :operator:`$near` operator but does not sort the results, +returns more information for each document found, and provides +additional operators. + +In its most simple form, the :dbcommand:`geoNear` command has the +following prototypical form: .. code-block:: javascript @@ -114,6 +118,37 @@ in the previous example: db.runCommand( {geoNear: "places", near: [ -74, 40.74 ] } ) +and the output is: + +.. code-block:: javascript + + { + "ns" : "test.places", + "near" : "0110000111111000000111111000000111111000000111111000", + "results" : [ + { + "dis" : 3, + "obj" : { + "_id" : ObjectId(" ... "), + "loc" : [ + -73, + 40 + ] + } + } + ], + "stats" : { + "time" : 2, + "btreelocs" : 0, + "nscanned" : 1, + "objectsLoaded" : 1, + "avgDistance" : 3, + "maxDistance" : 3.0000188685220253 + }, + "ok" : 1 + } + + .. seealso:: :ref:`geospatial-query-exact` @@ -122,50 +157,43 @@ in the previous example: Limit ````` - -By default, geospatial queries with :func:`find() -` return 100 documents. To impose a limit -on the result set, use the :func:`limit() ` method -with :func:`find() ` operator. The following is -the prototype operation: +The :func:`limit() ` method can be used with +:func:`find() ` to limit the number of results. +By default, geospatial queries with the :func:`find() +` method return 100 documents sorted by +distance. The following is the prototype operation: .. code-block:: javascript db.collection.find( { : { $near: [ x, y ] } } ).limit(n) -The following example will return only 20 results of the above query: - -.. code-block:: javascript - - db.places.find( { loc: { $near: [ -74, 40.74 ] } } ).limit(20) - -You may also use the ``num`` option with the :dbcommand:`geoNear` -command and the ``near`` parameter, as in the following prototype: +To limit the result set using the :dbcommand:`geoNear` command, use +the ``num`` option to limit results. The following is a prototype of +the command: .. code-block:: javascript db.runCommand( { geoNear: "collection", near: [ x, y ], num: z } ) -The following command returns the same results as the :operator:`near` -in the previous example: - -.. code-block:: javascript - - db.runCommand( { geoNear: "collection", near: [ -74, 40.74 ], num: 20 } ) - -The :func:`limit() ` method and ``near`` parameter do not limit -geospatial query results by distance, only the number of returned -:term:`document`. To limit geospatial search results by distance, -please see the :ref:`geospatial-query-distance` section. +The :func:`limit() ` method and ``near`` parameter do +not limit geospatial query results by distance, only the number of +results. To limit geospatial search results by distance, please see +the :ref:`geospatial-query-distance` section. .. note:: The :func:`limit() ` method and ``num`` option have - different performance characteristics. Geospatial queries with - :func:`limit() ` method will return 100 documents, - sort them, and finally the limit method is applied. Geospatial - queries with ``num`` option will only return the specified number - of documents unsorted. + different performance characteristics. Geospatial queries using + :func:`limit() ` method are slower than using + :dbcommand:`geoNear`. + + Geospatial queries with the :func:`find() ` + method will return 100 documents, sort them, and finally limit the + result set. Geospatial queries with the :dbcommand:`geoNear` and + ``num`` option will only return the specified number of unsorted + documents. + +.. TODO double check with greg... .. index:: geospatial queries; distance limit @@ -174,17 +202,16 @@ please see the :ref:`geospatial-query-distance` section. Distance ```````` -To limit the result set by a distance from the query point, MongoDB -provides the :operator:`$maxDistance` operator that you can use in -:func:`find() ` queries with the -:operator:`$near` operator, as in the following prototype: +To query geospatial data by distance, use the :operator:`$maxDistance` +operator with :func:`find() `, the function +prototype is: .. code-block:: javascript db.collection.find( { : { $near: [ x, y ] } , $maxDistance : z } ) -:dbcommand:`geoNear` provides equivalent functionality with the -``maxDistance`` option, as in the following prototype: +The equivalent :dbcommand:`geoNear` option is ``maxDistance``, the +prototype is: .. code-block:: javascript @@ -203,18 +230,21 @@ query results by the number of returned :term:`documents `. Bounded ~~~~~~~ -Bounded queries return documents that have coordinates within a shape -specified in the query. Bounded queries, using the :operator:`$within` -operator do not return sorted results and are faster than -:ref:`proximity queries ` +Bounded queries return documents within a particular shape and use the +:operator:`$within` operator to specify various shapes. -Using the :operator:`$within`, you can specify boundaries with the -following shapes: +The following is a list of acceptable shapes for bounded queries using +the :operator:`$within` operator: - circles, - rectangles, - polygons. +Bounded queries do not return sorted results and are faster than +:ref:`proximity queries ` + +.. TODO update $near in operator pages + Bounded queries take the following prototype form: .. code-block:: javascript @@ -225,19 +255,15 @@ Bounded queries take the following prototype form: } } ) -See the :ref:`geospatial-query-distance` section to perform geospatial -queries for a particular distance around a certain point. - The following sections provide examples of bounded queries using the :operator:`$within` operator. Circles ``````` -To return results within the :ref:`bounds ` -of a circle, you must specify the center and the radius of the circle, -using the :operator:`$within` operator and the :operator:`$circle` -option. Consider the following prototype query: +To query for documents within a circle, you must specify the center and the +radius of the circle, using the :operator:`$within` operator and the +:operator:`$center` option. Consider the following prototype query: .. code-block:: javascript @@ -254,13 +280,19 @@ with a radius of ``10``, using a geospatial index on the ``loc`` field: } } ) +The :operator:`$within` operator using :operator:`$center` may be +equivalent to using :operator:`$maxDistance`, but :operator:`$center` +has different performance characteristics. Queries using the +:operator:`$within` operator are not sorted, while :operator:`$near` +operator results are sorted. + Boxes ````` -To return results within the :ref:`bounds ` -of a rectangle or box, you must specify the lower-left and upper-right -corners of the shape, using the :operator:`$within` operator and the -:operator:`$box` option. Consider the following prototype query: +To query for documents that lie within a rectangle, you must specify only +the lower-left and upper-right corners for the :operator:`$box` option +using the :operator:`$within` operator. Consider the following +prototype query: .. code-block:: javascript @@ -281,44 +313,41 @@ Polygons .. versionadded:: 1.9 Support for polygon queries. -To return results within the :ref:`bounds ` -of a polygon, you must specify the points where the sides of the -polygon meet in an array, using the :operator:`$within` operator and -the :operator:`$box` option. Consider the following prototype query: +To query for documents that lie within a polygon, you must specify the +points of the polygon in an array, and use the :operator:`$polygon` +option with the :operator:`$within` operator. The last point in the +array will automatically be connected to the first point. Consider the following +prototype query: .. code-block:: javascript db.places.find({ "loc": { "$within": { "$polygon": [ points ] } } }) -The last point in the ``points`` array is automatically connected to -the first point in the polygon. Therefore, given the following array -of points: - -.. code-block:: javascript - - [0,0], [3,3], [6,0] - The following query will return all documents that have coordinates -that exist within the bounds of the polygon, where the sides of the -polygon connects at the above points using a geospatial index on the -``loc`` field: +that exist within ``[0,0]``, ``[3,3]`` , ``[6,0]``. The following is +an example: .. code-block:: javascript db.places.find({ "loc": { "$within": { "$polygon": [0,0], [3,3], [6,0] } } } ) +See the :ref:`geospatial-query-distance` section to perform geospatial +queries for a particular distance around a certain point. + .. _geospatial-query-spherical: Spherical ~~~~~~~~~ -If the coordinates in your :term:`document` represent points on a -spherical surface, :ref:`proximity ` and -some :ref:`bounded ` queries will not return -accurate results. To compensate, you can use the following spherical -queries that adjust for these differences. The following table provides a -list of spherical query operators and their flat surface equivalents: +By default, MongoDB uses flat geometry to calculate distances betwen +points. MongoDB also supports distance calculations using spherical +geometry to provide accurate distances for geospatial information +based on a sphere or earth. + +To calculate distances between points using spherical geometry instead +of flat geometry use the following spherical query operators, shown +with their flat geometry equivalents: ========================== =================== Spherical Flat @@ -327,14 +356,14 @@ list of spherical query operators and their flat surface equivalents: :operator:`$centerSphere` :operator:`$center` ========================== =================== -The :dbcommand:`geoNear` command returns documents assuming a spherical surface if -you specify the ``{ spherical: true }`` option. +The equivalent :dbcommand:`geoNear` option to calculate using +spherical geometry is the ``{ spherical: true }`` option. .. admonition:: Spherical Queries Use Radians for Distance - You must convert distances to radians when performing a spherical - query, and convert the distances returned from radians into the - units that your application uses. + For spherical operators to function properly, you must convert + distances to radians, and convert from radians to distances units + for your application. To convert: @@ -346,8 +375,8 @@ you specify the ``{ spherical: true }`` option. of the sphere (e.g. the Earth) in the units system that you want to convert the distance to. - The radius of the Earth is ``3963.192`` miles or ``6378.137`` - kilometers. + The radius of the Earth is approximately ``3963.192`` miles or + ``6378.137`` kilometers. The following query would return documents from the ``places`` collection, within the circle described by the center ``[ -74, 40.74 ]`` @@ -358,16 +387,13 @@ with a radius of ``100`` miles: db.places.find( { loc: { $centerSphere: [ [ -74, 40.74 ] , 100 / 3963.192 ] } } ) -Remember that you must convert the distance of the radius to -radians. This conversion *must* happen in your client -(i.e. application) code. You may also use the ``distanceMultiplier`` -option to the :dbcommand:`geoNear` to convert in the :program:`mongod` +You may also use the ``distanceMultiplier`` option to the +:dbcommand:`geoNear` to convert radians in the :program:`mongod` process, rather than in your application code. Please see the :ref:`distance multiplier ` section. -The following spherical proximity query, returns all documents in the -collection ``places`` within ``100`` miles from the point ``[ -74, -40.74 ]`` using the geospatial index. +The following spherical query, returns all documents in the collection +``places`` within ``100`` miles from the point ``[ -74, 40.74 ]``. .. code-block:: javascript @@ -402,9 +428,6 @@ The output of the above command would be: "ok" : 1 } -:dbcommand:`geoNear` returns documents in this result set sorted by -their distance from the ``[ -74, 40.74 ]`` point. - .. warning:: Spherical queries that wrap around the poles or at the transition @@ -421,16 +444,8 @@ their distance from the ``[ -74, 40.74 ]`` point. Distance Multiplier ~~~~~~~~~~~~~~~~~~~ -The ``distanceMultiplier`` option multiplies all distance values in -the ``distance`` field returned by :dbcommand:`geoNear` command by an -assigned value. - - Use ``distanceMultiplier`` with :ref:`spherical queries -` to convert the contents of the -``distance`` field returned in the extra output of the -:dbcommand:`geoNear` command from radians to distances. For more -information about the conversion, see the :ref:`spherical queries -` section. +The ``distanceMultiplier`` option multiplies all distances returned by +:dbcommand:`geoNear` command by an assigned value. .. note:: @@ -487,11 +502,9 @@ The output of the above command would be: Querying Haystack Indexes ------------------------- -Geospatial haystack indexes are a special geospatial index that that -allows MongoDB to optimize the query process for location queries, -given a coordinate and another field in your documents. To create -geospatial indexes with the haystack option and a particular -``bucketSize``, please see: :ref:`Haystack Index +Geospatial haystack indexes are a special index that is optimized for +a small area. To create geospatial indexes with the haystack option +and a particular ``bucketSize``, please see: :ref:`Haystack Index ` .. note:: @@ -500,19 +513,17 @@ geospatial indexes with the haystack option and a particular a particular location, as the closest documents could be far away compared to the ``bucketSize``. -The :dbcommand:`geoSearch` is the only way to return results using the -haystack index: :func:`find() ` and -:dbcommand:`geoNear` cannot access the haystack index. You must -specify both the coordinate and other field to geoSearch, which takes -the following prototypical form: +To query the haystack index, use the :dbcommand:`geoSearch` +command. You must specify both the coordinate and other field to +:dbcommand:`geoSearch`, which take the following prototypical form: .. code-block:: javascript db.runCommand( { geoSearch: , search: { : } } ) -For example, to return all documents with the value -``restaurants`` in the ``type`` field near the example point, the command would resemble: +For example, to return all documents with the value ``restaurants`` in +the ``type`` field near the example point, the command would resemble: .. code-block:: javascript @@ -525,6 +536,9 @@ For example, to return all documents with the value :ref:`Spherical queries ` are not currently supported by haystack indexes. + The :func:`find() ` method and + :dbcommand:`geoNear` command cannot access the haystack index. + .. _geospatial-multi-location: Multi-location Documents @@ -555,8 +569,8 @@ The values of the array may either be arrays holding coordinates, as in ``[ 55.5, 42.3 ]`` or embeded documents as in ``{ "lat": 55.3, "long": 40.2 }``. -You could then create an index on the ``locs`` field, as in the -following example: +You could then create a geospatial index on the ``locs`` field, as in +the following example: .. code-block:: javascript @@ -592,6 +606,9 @@ in the following example: db.records.ensureIndex( { "addresses.loc": "2d" } ) +For documents with multiple locations, results may have the same +document many times because of multiple matches. + To include the location field with the distance field in multi-location document queries, specify ``includeLocs: true`` in the :dbcommand:`geoNear` command. diff --git a/draft/core/geospatial-indexes.txt b/draft/core/geospatial-indexes.txt index d449d7cf312..5bd25679d36 100644 --- a/draft/core/geospatial-indexes.txt +++ b/draft/core/geospatial-indexes.txt @@ -8,15 +8,15 @@ Overview -------- MongoDB supports location-based queries and geospatial data with a -special index for coordinate data. The geospatial index stores :ref:`geohashes -`, and makes it possible to return documents -based on proximity to a point or within a bounded region. Geospatial -queries support coordinate systems on either flat and spherical surfaces. +special index. The geospatial index stores :ref:`geohashes +`, and makes it possible to query documents +based on proximity or within a bounded region. MongoDB can +calculate distances using flat or spherical geometry models. Additionally, geospatial haystack indexes provide additional -support for certain classes of region-based queries. +support for specific data distribution. -This document introduces the core concepts -that underpin geospatial queries and indexes in MongoDB. For more information, +This document introduces the core concepts that underpin geospatial +indexes in MongoDB. For more information, :doc:`/applications/geospatial-indexes` provide complete documentation of all location-based operations and queries. @@ -27,32 +27,33 @@ of all location-based operations and queries. Geospatial Indexes ------------------ -.. see:: :ref:`geospatial-coordinates` for an overview on modeling - location data in MongoDB. - -To use geospatial functions in MongoDB, model -location data in a 2D array, then create an index using the -:func:`ensureIndex ` method on this field -using the ``2d`` option. Consider the following prototype operation: +To create a geospatial index, use the :func:`ensureIndex +` method with the value ``2d`` for the +location field of your collection. Consider the following prototype +operation: .. code-block:: javascript db.collection.ensureIndex( { : "2d" } ) -After the ``2d`` index has been created, all queries using coordinates -will use this geospatial index. The index uses a :term:`geohash` -calculated from the coordinates. For more information on -:term:`geohash`, please refer to the :ref:`geohash -` section. +Almost all geospatial operators will query this index for location +data. The index comprises of :term:`geohashes ` calculated +from location values and the index's geospatial :ref:`range +`. For more information on :term:`geohash`, +please refer to the :ref:`geohash ` section. To perform queries on your geospatial data, please see -:doc:`/applications/geospatial-indexes`. +:ref:`geospatial-querying`. + +.. TODO fix this... weird duplicate reference? + +.. see:: :ref:`` for an overview on modeling + location data in MongoDB. .. note:: - MongoDB only supports *one* geospatial index per collection. As - with any MongoDB index, any single query can only - use one index. Creating more than one geospatial index with a + MongoDB only supports *one* geospatial index per + collection. Creating more than one geospatial index with a collection will produce unexpected results. .. _geospatial-indexes-range: @@ -60,30 +61,21 @@ To perform queries on your geospatial data, please see Range ~~~~~ -All geospatial indexes are bounded. MongoDB will -return an error and reject documents with coordinate data outside of -the specified range. The default range assumes latitude and longitude -data, and are between -180 inclusive and 180 -non-inclusive (i.e. ``[-180, 180)``.) +All geospatial indexes are bounded to a range as this range is used to +compute :term:`geohash` values. MongoDB will return an error and +reject documents with coordinate data outside of the specified range. +The default range assumes latitude and longitude data, and are between +-180 inclusive and 180 non-inclusive (i.e. ``[-180, 180)``.) To configure the range of a geospatial index, use the ``min`` and ``max`` options with the :func:`ensureIndex() ` -operation, as in the following prototype. +operation, as in the following prototype: .. code-block:: javascript db.collection.ensureIndex( { : "2d" } , { min: , max: } ) -The following operation will create an index on the ``places`` -collection, for coordinates in the ``loc`` field, with the range -between ``-90`` and ``90``: - -.. code-block:: javascript - - db.places.ensureIndex( { loc: "2d" } , - { min: 90 , max: 90 } ) - For more information see the :ref:`geospatial precision ` and :ref:`geohash ` sections. @@ -93,19 +85,20 @@ For more information see the :ref:`geospatial precision Precision ~~~~~~~~~ -Geospatial indexes use "bits" to represent precision, or -resolution. Higher bit values allow MongoDB to return more precise -results, at the expense of speed. For more information on the +Geospatial indexes consist of :term:`geohash` values and the number of +bits determine the precision of the index. More bits create more +precise :term:`geohash` values, which allow MongoDB to return more +precise results. Fewer bits create a shorter :term:`geohash` value, +which allow for faster processing. For more information on the relationship between bits and precision, see the :ref:`geohash ` section. -By default, geospatial indexes in MongoDB have 26 bits of precision, -although precision is configurable upon index creation and MongoDB -supports up to 32 bits of precision. With 26 bits of precision, using -the default range of -180 to 180, geospatial data can be precise to roughly 2 -feet or about 60 centimeters. +The precision of geospatial indexes can be configured upto 32 bits. By +default, geospatial indexes use 26 bits of precision, which is precise +to roughly 2 feet or about 60 centimeters using the default range of +-180 to 180. -You can set the precision of a geospatial index during creation by +The precision of a geospatial index can be configured during creation by specifying the ``bits`` option to the :func:`ensureIndex() ` method, as in the following prototype: @@ -114,36 +107,37 @@ specifying the ``bits`` option to the :func:`ensureIndex() db.collection.ensureIndex( {: "2d"} , { bits: } ) -Only create an index with fewer than 26 bits *if* your the data in -your collection is less precise and/or you're willing to sacrifice +Only create an index with fewer than 26 bits *if* the data in your +collection is less precise and/or you're willing to sacrifice precision for query speed. Compound Indexes ~~~~~~~~~~~~~~~~ -MongoDB supports :ref:`compound indexes ` where -one component holds coordinate data. For queries that include these -fields, MongoDB will use this index for a larger portion of these -operations, which will improve performance for these queries. +:ref:`Compound indexes ` can be used with +geospatial data to improve performance that query all these fields. -Use an operation that resembles the following to create a geospatial -index with a compound key. +To create compound index with geospatial data and another field, the +prototype form is: .. code-block:: javascript db.collection.ensureIndex( { : "2d", : 1 } ); -These indexes support regular geospatial queries as well as queries where you must filter both by -location and by another field. For example, if you need to return a -list of restaurants near a given point, but you want to optionally -filter restaurants by type, such as "take-out," or -"bar" stored in the ``type`` field. +This index will now support regular geospatial queries as well as +queries where you must filter both by location and by another field. -.. note:: +For example, to create a compound index on the ``loc`` field and the +``type`` field, the command is: + +.. code-block:: javascript - Limits in geospatial queries are always applied to the geospatial - component first. This will affect the results if you specify - additional sort operations. + db.storeInfo.ensureIndex( { loc: "2d", type: 1 } ); + +This will support geospatial queries as well as any query on the +``type`` field. This index can return a list of restaurants near a +given point, which can optionally filter restaurants by the ``type``, +such as "take-out," or "bar". .. see also: ":ref:``" and ":ref:``" @@ -152,57 +146,58 @@ filter restaurants by type, such as "take-out," or Haystack Index ~~~~~~~~~~~~~~ -Geospatial haystack indexes make it possible to tune the -distribution of your data and build a special bucket -index. Haystack indexes improve query performance for queries limited -to a specific area. +Geospatial haystack indexes make it possible to tune for the +distribution of your data and build a special bucket index. Haystack +indexes improve query performance for queries limited to a specific +area. .. note:: - Haystack indexes are not suited to returning the closest documents to - a particular location, as the closest documents could be far away - compared to the ``bucketSize``. + Haystack indexes are tuned to the ``bucketSize`` and are not suited + to returning the closest documents to a particular location, + because the closest documents could be further away than to the + ``bucketSize``. -To build a :term:`geoHaystack` index, specify the ``geoHaystack`` for the -location field and a ``bucketSize`` parameter . The ``bucketSize`` -parameter determines the granularity of the bucket index. A -``bucketSize`` of ``1`` creates an index that stores keys within a single unit -in the coordinate in the same bucket. +The following command is the prototype to build a :term:`geoHaystack` +index: .. code-block:: javascript db.collection.ensureIndex({ : "geoHaystack", type: 1 }, { bucketSize: }) -By default, all queries that use a geospatial haystack index will return 50 -documents. +The ``bucketSize`` parameter determines the granularity of the +index. A bucket value of ``5`` creates an index that stores keys +within 5 units of the coordinate in the same bucket. -To query geohaystack indexes, you *must* use the :dbcommand:`geoSearch` +Geohaystack indexes are only queried by the :dbcommand:`geoSearch` command, please see the :ref:`Querying Haystack Indexes -` section. +` section for command details. + +:ref:`Spherical queries ` are not +supported by geohaystack indexes. -:ref:`Spherical queries ` are not -supported by haystack indexes. +By default, all queries that use a geospatial haystack index will return 50 +documents. -.. _geospatial-spherical-representation: +.. _geospatial-spherical-geometry: -Spatial Representation Systems ------------------------------- +Distance Calculation Modes +-------------------------- -MongoDB supports two systems for representing and returning geospatial -results. The default representation is flat and assumes coordinates -points are on a flat surface, which is sufficient for many -applications. For coordinate points that refer to locations on a -spherical surface, (i.e. coordinates on Earth) spherical queries will -provide results that account for curvature of the Earth's surface. +MongoDB can calculate distances using two geometry systems: flat and +spherical. The default flat geometry, which model points on a flat +surface. To use spherical geometry to calculate distances, use +spherical query operators, which model points on a spherical surface +(i.e. coordinates on Earth.) .. note:: There is no difference between flat and spherical *data* as stored - in MongoDB. Rather, the only difference between spherical and flat - geospatial systems in MongoDB is in the **queries**. + in MongoDB. Rather, the only difference is the distance + formulas to calculate in flat and spherical geometry. -For more information on query operations for spherical systems see the +For more information on query operations for spherical geometry see the :ref:`spherical queries ` section. .. _geospatial-geohash: @@ -211,7 +206,8 @@ Geohash ------- To create a geospatial index, MongoDB computes the :term:`geohash` -value for the coordinate pair in the specified values. +value for coordinate pairs within the specified :term:`range +`. To calculate a geohash value, continuously divide a 2D map into quadrants. Then, assign each quadrant a two bit value. For example, a @@ -224,18 +220,18 @@ two bit representation of four quadrants would be: 00 10 These two bit values, ``00``, ``01``, ``10``, and ``11``, represent -each of the quadrants, and points within that quadrant. For a -:term:`geohash` with two bits of resolution, a point in the bottom +each of the quadrants, and all points within that quadrant. For a +:term:`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. To identify quadrants within a sub-quadrant, take the -geohash for the containing quadrant (e.g. ``01``) and concatenate the geohash for -the sub-quadrant. Therefore, the geohash for -the upper-right quadrant is ``11``, the geohash for the sub-quadrants would be: -``1101``, ``1111``, ``1110``, and ``1100``. +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``, respectfully. To calculate a more precise :term:`geohash`, continue dividing the sub-quadrant, concatenate the two-bit identifier for each division. The