From 0ac39fed45db434612e262961d74f67485bce690 Mon Sep 17 00:00:00 2001 From: Andrew Leung Date: Sat, 4 Aug 2012 14:50:16 -0400 Subject: [PATCH 1/6] rewording to spherical geometry --- draft/applications/geospatial-indexes.txt | 57 ++++++++++++----------- draft/core/geospatial-indexes.txt | 30 +++++++----- 2 files changed, 47 insertions(+), 40 deletions(-) diff --git a/draft/applications/geospatial-indexes.txt b/draft/applications/geospatial-indexes.txt index 96a19c4c096..ebf4bda7b64 100644 --- a/draft/applications/geospatial-indexes.txt +++ b/draft/applications/geospatial-indexes.txt @@ -33,13 +33,13 @@ return documents. .. 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 assumes calculate distances using flat geometry + and all distances calculated by the :dbcommand:`geoNear` use the + Pythagorean distance formula. - 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 `, using + :ref:`spherical query operations `. .. index:: geospatial queries; exact @@ -313,12 +313,10 @@ polygon connects at the above points using a geospatial index on the 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: +To calculate distances between points using spherical geometry instead +of flat geometry use the following spherical query operators. The +following table provides a list of spherical query operators and their +flat geometry equivalents: ========================== =================== Spherical Flat @@ -327,14 +325,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 :dbcommand:`geoNear` command using the ``{ spherical: true }`` +option will use spherical geometry to calculate distances. .. 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. + You must convert distances to radians when using a spherical + operators, and convert from radians to distances units that your + application uses. To convert: @@ -346,8 +344,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 ]`` @@ -359,11 +357,11 @@ with a radius of ``100`` miles: 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` -process, rather than in your application code. Please see the -:ref:`distance multiplier ` section. +radians. This conversion *must* happen in your application code. You +may also use the ``distanceMultiplier`` option to the +:dbcommand:`geoNear` to convert 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, @@ -410,12 +408,16 @@ their distance from the ``[ -74, 40.74 ]`` point. Spherical queries that wrap around the poles or at the transition from ``-180`` to ``180`` longitude raise an error. +.. TODO add note that this is a bug in MongoDB + .. note:: While the default Earth-like bounds for geospatial indexes are between ``-180`` inclusive, and ``180``, valid values for latitude are between ``-90`` and ``90``. +.. TODO where did this come from?! + .. _geospatial-distance-multiplier: Distance Multiplier @@ -427,10 +429,9 @@ 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. +``distance`` field returned in documents of the :dbcommand:`geoNear` +command. For more information about the conversion, see the +:ref:`spherical queries ` section. .. note:: diff --git a/draft/core/geospatial-indexes.txt b/draft/core/geospatial-indexes.txt index d449d7cf312..5560b0112d5 100644 --- a/draft/core/geospatial-indexes.txt +++ b/draft/core/geospatial-indexes.txt @@ -10,8 +10,8 @@ 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. +based on proximity to a point or within a bounded region. MongoDB can +calculate distances between points using flat or spherical geometry. Additionally, geospatial haystack indexes provide additional support for certain classes of region-based queries. @@ -181,28 +181,34 @@ To query geohaystack indexes, you *must* use the :dbcommand:`geoSearch` command, please see the :ref:`Querying Haystack Indexes ` section. -:ref:`Spherical queries ` are not +:ref:`Spherical queries ` are not supported by haystack indexes. -.. _geospatial-spherical-representation: +.. _geospatial-spherical-geometry: + +.. TODO think of better title: Distances in Flat and Spherical +.. Geometry +.. using flat or spherical geometry +.. Spherical and Flat Geometry System Spatial Representation Systems ------------------------------ -MongoDB supports two systems for representing and returning geospatial -results. The default representation is flat and assumes coordinates +MongoDB supports two geometry systems for calculating distances +between points. The default is flat geometry 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. +applications. To calculate distance using spherical geometry, such as +points that refer to locations on a spherical surface, +(i.e. coordinates on Earth) MongoDB's spherical query operatorss will +provide results using this geometrical system. .. 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 between the distance + calculation in spherical and flat geometry systems. -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: From 4d6896763517cabcf13b6a8930b6eeddf27d154e Mon Sep 17 00:00:00 2001 From: Andrew Leung Date: Sat, 4 Aug 2012 15:57:53 -0400 Subject: [PATCH 2/6] re-editing geospatial core document --- draft/applications/geospatial-indexes.txt | 6 + draft/core/geospatial-indexes.txt | 184 ++++++++++++---------- 2 files changed, 103 insertions(+), 87 deletions(-) diff --git a/draft/applications/geospatial-indexes.txt b/draft/applications/geospatial-indexes.txt index ebf4bda7b64..e546118a01a 100644 --- a/draft/applications/geospatial-indexes.txt +++ b/draft/applications/geospatial-indexes.txt @@ -167,6 +167,12 @@ please see the :ref:`geospatial-query-distance` section. queries with ``num`` option will only return the specified number of documents unsorted. +.. note:: + + Limits in geospatial queries are always applied to the geospatial + component first. This will affect the results if you specify + additional sort operations. + .. index:: geospatial queries; distance limit .. _geospatial-query-distance: diff --git a/draft/core/geospatial-indexes.txt b/draft/core/geospatial-indexes.txt index 5560b0112d5..50ee265ad2e 100644 --- a/draft/core/geospatial-indexes.txt +++ b/draft/core/geospatial-indexes.txt @@ -9,14 +9,16 @@ 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. MongoDB can -calculate distances between points using flat or spherical geometry. +`, and makes it possible to query documents +based on proximity or within a bounded region. MongoDB can +calculate distances using flat or spherical geometry. Additionally, geospatial haystack indexes provide additional -support for certain classes of region-based queries. +support for tuning indexes. -This document introduces the core concepts -that underpin geospatial queries and indexes in MongoDB. For more information, +.. TODO double check haystack benefits. + +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. @@ -30,29 +32,28 @@ 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 use geospatial operators in MongoDB, use the :func:`ensureIndex +` method with the ``2d`` value on +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 +` section. To perform queries on your geospatial data, please see :doc:`/applications/geospatial-indexes`. .. 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,29 +61,31 @@ 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, +because the :term:`geohash` value will be invalid. 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``: +.. TODO this might not be necessary... + +The following example command will create a geospatial index with a +range between ``-90`` and ``90``: .. code-block:: javascript db.places.ensureIndex( { loc: "2d" } , - { min: 90 , max: 90 } ) + { min: -90 , max: 90 } ) For more information see the :ref:`geospatial precision ` and :ref:`geohash @@ -93,57 +96,63 @@ 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: +.. TODO question: would the index recalculate geohashes if we +.. reconfigure the bits option after the index has been made? or do we +.. need to drop the index? + .. code-block:: javascript 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,37 +161,39 @@ 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 the index to 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 haystack indexes. +supported by geohaystack indexes. + +By default, all queries that use a geospatial haystack index will return 50 +documents. .. _geospatial-spherical-geometry: @@ -195,18 +206,16 @@ Spatial Representation Systems ------------------------------ MongoDB supports two geometry systems for calculating distances -between points. The default is flat geometry and assumes coordinates -points are on a flat surface, which is sufficient for many -applications. To calculate distance using spherical geometry, such as -points that refer to locations on a spherical surface, -(i.e. coordinates on Earth) MongoDB's spherical query operatorss will -provide results using this geometrical system. +between points. The default calculation is based on flat geometry, +which points lie on a flat surface. User spherical query operators to +calculate distances between points that lie 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 is between the distance - calculation in spherical and flat geometry systems. + 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 geometry see the :ref:`spherical queries ` section. @@ -217,7 +226,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 @@ -230,18 +240,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 From 4cca966b8a7563db22b96d8ce5801d5023493338 Mon Sep 17 00:00:00 2001 From: Andrew Leung Date: Sat, 4 Aug 2012 20:30:11 -0400 Subject: [PATCH 3/6] re-editing geospatial apps --- draft/applications/geospatial-indexes.txt | 107 +++++++++++----------- 1 file changed, 51 insertions(+), 56 deletions(-) diff --git a/draft/applications/geospatial-indexes.txt b/draft/applications/geospatial-indexes.txt index e546118a01a..4dafc74d51f 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,27 @@ 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. + +.. TODO find a better way to say this... (rewrite 3x) +The :func:`find() ` method for geospatial data +is same as querying any other data. This provides simplicity. + +The :dbcommand:`geoNear` command is more specialized as it returns +detailed geospatial information such as distances, ... This provides +addtional benefit when only working with geospatial data. + +.. TODO does it make sense to have this here?? .. note:: - By default MongoDB assumes calculate distances using flat geometry - 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 distances based on :ref:`spherical - geometry `, using - :ref:`spherical query operations `. + geometry ` by using the + :ref:`spherical query operators `. .. index:: geospatial queries; exact @@ -49,25 +54,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 +74,29 @@ 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: - -.. code-block:: javascript +.. TODO show example & output (i.e. show that it's the same as normal ops) - db.places.find( { loc: { $near: [ -74, 40.74 ] } } ) +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. -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 ]``. +.. TODO what are the additional operators for geoNear that can't be +.. used by find()?? -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: +In its most simple form, the :dbcommand:`geoNear` command has the +following prototypical form: .. code-block:: javascript @@ -114,6 +109,9 @@ in the previous example: db.runCommand( {geoNear: "places", near: [ -74, 40.74 ] } ) +.. TODO show output (i.e. highlight differences to $near) + + .. seealso:: :ref:`geospatial-query-exact` @@ -123,8 +121,11 @@ in the previous example: Limit ````` +The :func:`limit() ` method can be used with +:func:`find() ` + By default, geospatial queries with :func:`find() -` return 100 documents. To impose a limit +` return 100 documents sorted by distance. To limit on the result set, use the :func:`limit() ` method with :func:`find() ` operator. The following is the prototype operation: @@ -133,13 +134,7 @@ the prototype operation: 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` +To the ``num`` option with the :dbcommand:`geoNear` command and the ``near`` parameter, as in the following prototype: .. code-block:: javascript From 141178d61a4211126cb1460177b06d71daf92a5d Mon Sep 17 00:00:00 2001 From: Andrew Leung Date: Sat, 4 Aug 2012 20:31:19 -0400 Subject: [PATCH 4/6] re-editing geospatial apps --- draft/applications/geospatial-indexes.txt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/draft/applications/geospatial-indexes.txt b/draft/applications/geospatial-indexes.txt index 4dafc74d51f..078b9741864 100644 --- a/draft/applications/geospatial-indexes.txt +++ b/draft/applications/geospatial-indexes.txt @@ -121,8 +121,12 @@ in the previous example: Limit ````` +.. TODO double check with greg... will limit really stop 100 documents +.. being searched for (i.e. if only 99 documents are found, limit(98) +.. will return sooner? ) + The :func:`limit() ` method can be used with -:func:`find() ` +:func:`find() ` to limit the By default, geospatial queries with :func:`find() ` return 100 documents sorted by distance. To limit From 02305ecd67a32fa4a4fcb1a8e861ab3b826d3255 Mon Sep 17 00:00:00 2001 From: Andrew Leung Date: Tue, 7 Aug 2012 14:09:57 -0400 Subject: [PATCH 5/6] editing save --- draft/applications/geospatial-indexes.txt | 66 ++++++++++------------- 1 file changed, 28 insertions(+), 38 deletions(-) diff --git a/draft/applications/geospatial-indexes.txt b/draft/applications/geospatial-indexes.txt index 078b9741864..a383efdf634 100644 --- a/draft/applications/geospatial-indexes.txt +++ b/draft/applications/geospatial-indexes.txt @@ -120,57 +120,43 @@ in the previous example: Limit ````` - -.. TODO double check with greg... will limit really stop 100 documents -.. being searched for (i.e. if only 99 documents are found, limit(98) -.. will return sooner? ) - The :func:`limit() ` method can be used with -:func:`find() ` to limit the - -By default, geospatial queries with :func:`find() -` return 100 documents sorted by distance. To limit -on the result set, use the :func:`limit() ` method -with :func:`find() ` operator. The following is -the prototype operation: +: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) -To 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`. -.. note:: + 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. - Limits in geospatial queries are always applied to the geospatial - component first. This will affect the results if you specify - additional sort operations. +.. TODO double check with greg... .. index:: geospatial queries; distance limit @@ -179,15 +165,19 @@ 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() `. Results with this operator +will not exceed the distance specified. .. code-block:: javascript db.collection.find( { : { $near: [ x, y ] } , $maxDistance : z } ) +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: + :dbcommand:`geoNear` provides equivalent functionality with the ``maxDistance`` option, as in the following prototype: From fff1f316a1fffd6b1e3dc781f32018c5f84de5d2 Mon Sep 17 00:00:00 2001 From: Andrew Leung Date: Wed, 8 Aug 2012 10:58:44 -0400 Subject: [PATCH 6/6] re-edited geospatial docs --- draft/applications/geospatial-indexes.txt | 221 ++++++++++++---------- draft/core/geospatial-indexes.txt | 64 +++---- 2 files changed, 143 insertions(+), 142 deletions(-) diff --git a/draft/applications/geospatial-indexes.txt b/draft/applications/geospatial-indexes.txt index a383efdf634..824dc3e7635 100644 --- a/draft/applications/geospatial-indexes.txt +++ b/draft/applications/geospatial-indexes.txt @@ -28,13 +28,15 @@ There are two operators to query geospatial data in MongoDB, the general :func:`find() ` method and the specialized :dbcommand:`geoNear` command. -.. TODO find a better way to say this... (rewrite 3x) -The :func:`find() ` method for geospatial data -is same as querying any other data. This provides simplicity. +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 such as distances, ... This provides -addtional benefit when only working with geospatial data. +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?? @@ -43,7 +45,7 @@ addtional benefit when only working with geospatial data. By default, MongoDB calculates distances using flat geometry. MongoDB can also calculate distances based on :ref:`spherical - geometry ` by using the + geometry ` by using :ref:`spherical query operators `. .. index:: geospatial queries; exact @@ -85,16 +87,23 @@ The prototype form for the :operator:`$near` operator is: db.collection.find( { : { $near: [ x, y ] } } ) -.. TODO show example & output (i.e. show that it's the same as normal ops) +For example, + +.. code-block:: javascript + + db.places.find( { loc: {$near: [-70,40] } }) + +and the output is: + +.. 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. -.. TODO what are the additional operators for geoNear that can't be -.. used by find()?? - In its most simple form, the :dbcommand:`geoNear` command has the following prototypical form: @@ -109,7 +118,35 @@ in the previous example: db.runCommand( {geoNear: "places", near: [ -74, 40.74 ] } ) -.. TODO show output (i.e. highlight differences to $near) +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:: @@ -165,21 +202,16 @@ the :ref:`geospatial-query-distance` section. Distance ```````` -To query geospatial data by distance, use the :operator:`$maxDistance` operator -with :func:`find() `. Results with this operator -will not exceed the distance specified. +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 } ) -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: - -: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 @@ -198,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 @@ -220,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 @@ -249,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 @@ -276,42 +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 ~~~~~~~~~ +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. The -following table provides a list of spherical query operators and their -flat geometry equivalents: +of flat geometry use the following spherical query operators, shown +with their flat geometry equivalents: ========================== =================== Spherical Flat @@ -320,14 +356,14 @@ flat geometry equivalents: :operator:`$centerSphere` :operator:`$center` ========================== =================== -The :dbcommand:`geoNear` command using the ``{ spherical: true }`` -option will use spherical geometry to calculate distances. +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 using a spherical - operators, and convert from radians to distances 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: @@ -351,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 application code. You -may also use the ``distanceMultiplier`` option to the -:dbcommand:`geoNear` to convert in the :program:`mongod` process, -rather than in your application code. Please see the :ref:`distance -multiplier ` section. +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 @@ -395,38 +428,24 @@ 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 from ``-180`` to ``180`` longitude raise an error. -.. TODO add note that this is a bug in MongoDB - .. note:: While the default Earth-like bounds for geospatial indexes are between ``-180`` inclusive, and ``180``, valid values for latitude are between ``-90`` and ``90``. -.. TODO where did this come from?! - .. _geospatial-distance-multiplier: 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 documents of the :dbcommand:`geoNear` -command. 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:: @@ -483,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:: @@ -496,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 @@ -521,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 @@ -551,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 @@ -588,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 50ee265ad2e..5bd25679d36 100644 --- a/draft/core/geospatial-indexes.txt +++ b/draft/core/geospatial-indexes.txt @@ -8,14 +8,12 @@ Overview -------- MongoDB supports location-based queries and geospatial data with a -special index for coordinate data. The geospatial index stores :ref:`geohashes +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. +calculate distances using flat or spherical geometry models. Additionally, geospatial haystack indexes provide additional -support for tuning indexes. - -.. TODO double check haystack benefits. +support for specific data distribution. This document introduces the core concepts that underpin geospatial indexes in MongoDB. For more information, @@ -29,11 +27,8 @@ 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 operators in MongoDB, use the :func:`ensureIndex -` method with the ``2d`` value on +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: @@ -44,11 +39,16 @@ operation: 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:: @@ -63,10 +63,9 @@ Range 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, -because the :term:`geohash` value will be invalid. The default range -assumes latitude and longitude data, and are between -180 inclusive -and 180 non-inclusive (i.e. ``[-180, 180)``.) +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() ` @@ -77,16 +76,6 @@ operation, as in the following prototype: db.collection.ensureIndex( { : "2d" } , { min: , max: } ) -.. TODO this might not be necessary... - -The following example command will create a geospatial index with a -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. @@ -113,10 +102,6 @@ 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: -.. TODO question: would the index recalculate geohashes if we -.. reconfigure the bits option after the index has been made? or do we -.. need to drop the index? - .. code-block:: javascript db.collection.ensureIndex( {: "2d"} , @@ -161,7 +146,7 @@ such as "take-out," or "bar". Haystack Index ~~~~~~~~~~~~~~ -Geospatial haystack indexes make it possible to tune the index to the +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. @@ -197,18 +182,13 @@ documents. .. _geospatial-spherical-geometry: -.. TODO think of better title: Distances in Flat and Spherical -.. Geometry -.. using flat or spherical geometry -.. Spherical and Flat Geometry System - -Spatial Representation Systems ------------------------------- +Distance Calculation Modes +-------------------------- -MongoDB supports two geometry systems for calculating distances -between points. The default calculation is based on flat geometry, -which points lie on a flat surface. User spherical query operators to -calculate distances between points that lie on a spherical 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::