Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
167 changes: 135 additions & 32 deletions draft/applications/geospatial-indexes.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,13 @@ 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
<geospatial-query-operators>`. For more information about the
geospatial indexes and operations see the :doc:`/applications/geospatial-indexes`.
<geospatial-query-operators>`. For more information about
geospatial indexes and operations see the :doc:`/applications/geospatial-indexes` document.

.. _geospatial-coordinates:

.. This include inserts an introduction to geospatial modeling.
"Representing Coordinate Data"
.. include:: /includes/geospatial-coordinates.rst

.. index:: geospatial queries
Expand All @@ -24,7 +26,7 @@ Queries

MongoDB provides special :ref:`geospatial query operators
<geospatial-query-operators>` for performing queries on location data
inside of normal :func:`find() <db.collection.find()>` operation. The
inside the normal :func:`find() <db.collection.find()>` operator. The
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

method.

:dbcommand:`geoNear` command also returns results using geospatial
indexes, but also includes additional geospatial information in the
return documents.
Expand All @@ -37,10 +39,12 @@ return documents.

MongoDB can also calculate and return accurate results for
locations in a :ref:`spherical <geospatial-spherical-representation>`
coordinate system, suing :ref:`spherical query operations <geospatial-spherical-queries>`.
coordinate system, using :ref:`spherical query operations <geospatial-spherical-queries>`.

.. index:: geospatial queries; exact

.. _geospatial-query-exact:

Exact
~~~~~

Expand All @@ -55,11 +59,11 @@ following prototypical form:
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 ``[ 42, 42 ]``, consider the following example:
field that are exactly ``[ -74, 40.74 ]``, consider the following example:

.. code-block:: javascript

db.places.find( { "loc": [ 42, 42 ] } )
db.places.find( { "loc": [ -74, 40.74 ] } )

Exact geospatial queries only have applicability for a limited selection of
cases, :ref:`proximity <geospatial-query-proximity>` and :ref:`bounded
Expand Down Expand Up @@ -97,7 +101,7 @@ 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 prototype form:
command has the following prototypical form:

.. code-block:: javascript

Expand All @@ -110,19 +114,26 @@ in the previous example:

db.runCommand( {geoNear: "places", near: [ -74, 40.74 ] } )

.. seealso::

:ref:`geospatial-query-exact`

.. _geospatial-query-limit:

Limit
`````

To impose a limit on the result set other than the default 100
document limit, use the :func:`limit() <cursor.limit()>` method with
:func:`find() <db.collection.find()>` queries, in the following
prototype operation.
By default, geospatial queries with :func:`find()
<db.collection.find()>` return 100 documents. To impose a limit
on the result set, use the :func:`limit() <cursor.limit()>` method
with :func:`find() <db.collection.find()>` operator. The following is
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not an operator

the prototype operation.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needs a colon.

I know it's sort of formulaic, but "consider the following prototype operation:" has the benefit of telling the reader to do something, rather than just declaring the identity (i.e. "this is it!")


.. code-block:: javascript

db.collection.find( { <location field>: { $near: [ x, y ] } } ).limit(n)

The following example, will return only 20 results of the above query:
The following example will return only ``20`` results of the above query:
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

20 is not an example, it means the actual number 20.


.. code-block:: javascript

Expand All @@ -140,11 +151,18 @@ in the previous example:

.. code-block:: javascript

db.runCommand( {geoNear: "collection", near: [ -74, 40.74 ], num: 20 } )
db.runCommand( { geoNear: "collection", near: [ -74, 40.74 ], num: 20 } )

The :func:`limit() <cursor.limit()>` and :operator:`near` do not limit
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fix.

geospatial query results by distance, only the number of returned
:term:`documents`. To limit geospatial search results by distance,
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

glossary terms are singular except in cases where the term is a collective noun (i.e. BSON types)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

documents is singular in the glossary. so use

 :term:`documents <document>`.

you can build the manual to catch this kind of error. (it's common, and I make this kind of error a bunch, but as we're getting a doc in shape for publication, the fewer of these there are, the better.

please see the :ref:`geospatial-query-distance` section.

.. index:: $maxDistance
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

delete this line.

.. index:: geospatial queries; distance limit

.. _geospatial-query-distance:

Distance
````````

Expand All @@ -168,23 +186,26 @@ Specify the distance in the ``maxDistance`` option using the same units
as the coordinate system specified. For example, if the indexed
location data is in meters, the distance units are also in meters.

To limit geospatial query results by the number of returned
:term:`documents`, please see the :ref:`geospatial-query-limit` section.

.. _geospatial-within:
.. _geospatial-query-bounded:

Bounded
~~~~~~~

Bounded queries return results within the boundaries of a shape
specified in the query. The :operator:`$within` operator allows you to
construct these quires. Bounded queries do not return sorted results:
Bounded queries return results within the boundaries of a specified shape
in the query. The :operator:`$within` operator allows you to
construct these queries. Bounded queries do not return sorted results,
as a result these queries are faster than :ref:`proximity
<geospatial-query-proximity>` queries.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the change from a shape specified, to a specified shape, changes the meaning in a subtle and not terribly useful way. "a shape specified in the query," refers to an instance of a shape, where as "specified shape," is redundant because of the word "within" (what else would you do in a query except specify something?)

Also, I think we ought to take a step back from this paragraph because the wording isn't getting better with these tweaks. Save copy editing, lets just go with the following:

 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 <geospatial-query-proximity>`


Using the :operator:`$within`, you can specify boundaries with the
following shapes:

- circles,
- rectangles (i.e. "boxes,") or
- rectangles,
- polygons.

Bounded queries take the following prototype form:
Expand All @@ -197,6 +218,9 @@ Bounded queries take the following prototype form:
}
} )

To perform geospatial queries for a particular distance around a
certain point, please see the :ref:`geospatial-query-distance` section.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

see above note.

also "particular" seems redundant.


The following sections provide examples of bounded queries using the
:operator:`$within` operator.

Expand Down Expand Up @@ -237,12 +261,12 @@ corners of the shape, using the :operator:`$within` operator and the

The following query will return all documents that have coordinates
that exist within the rectangle, where the lower-left corner is at ``[
0, 0 ]`` and the upper-right corner is at ``[ 5, 5 ]`` using a
0, 0 ]`` and the upper-right corner is at ``[ 3, 3 ]`` using a
geospatial index on the ``loc`` field:

.. code-block:: javascript

db.places.find( { "loc": { "$within": { "$box": [ [0, 0] , [5, 5] ] } } } )
db.places.find( { "loc": { "$within": { "$box": [ [0, 0] , [3, 3] ] } } } )

Polygons
````````
Expand All @@ -265,7 +289,7 @@ of points:

.. code-block:: javascript

[4,0], [3,2], [2,3], [2,4], [4,5]
[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
Expand All @@ -275,20 +299,19 @@ polygon connects at the above points using a geospatial index on the
.. code-block:: javascript

db.places.find({ "loc": { "$within": { "$polygon":
[4,0], [3,2], [2,3], [2,4], [4,5]
} } })
[0,0], [3,3], [6,0] } } } )

.. _geospatial-query-spherical:

Spherical
~~~~~~~~~

If the coordinates in your documents represent points on a
spherical plane, :ref:`proximity <geospatial-query-proximity>` and
If the coordinates in your :term:`documents` represent points on a
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

singular

spherical surface, :ref:`proximity <geospatial-query-proximity>` and
some :ref:`bounded <geospatial-query-bounded>` queries will not return
accurate results. To compensate, you can use the following spherical
queries which adjust for these errors. The following table provides a
list of spherical query operators and their flat system equivalents:
queries which adjust for these differences. The following table provides a
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/which/that/

list of spherical query operators and their flat surface equivalents:

========================== ===================
Spherical Flat
Expand All @@ -297,7 +320,7 @@ list of spherical query operators and their flat system equivalents:
:operator:`$centerSphere` :operator:`$center`
========================== ===================

The :dbcommand:`geoNear` will return results for spherical systems if
The :dbcommand:`geoNear` will return results for spherical surface if
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

.. will return results assuming a spherical surface...

you specify the ``{ spherical: true }`` option to the command.

.. admonition:: Spherical Queries Use Radians for Distance
Expand All @@ -321,16 +344,19 @@ you specify the ``{ spherical: true }`` option to the command.

The following query would return documents from the ``places``
collection, within the circle described by the center ``[ -74, 40.74 ]``
with a radius of ``100`` kilometers:
with a radius of ``100`` miles:

.. code-block:: javascript

db.places.find( { loc: { $centerSphere: [ [ -74, 40.74 ] ,
100 / 6378.137 ] } } )
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.
(i.e. application) code. You may also utilize the
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use.

:option:`distanceMultiplier` option to have the conversion happen on
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

 ``distanceMultiplier`` option to the :dbcommand:`geoSearch`

(or geoNear?)

the server code. Please see the :ref:`distance multiplier
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you mean "in the :program:mongod process, rather than your application code." rather than "on the server code."

Use the ``distanceMultipler`` option to the :dbcommand:`geoNear` to convert the results of
the  :dbcommand:`geoNear` operation in the :program:`mongod` process rather than your 
application code. See the :ref:`distance multiplier <>` section for more information.

<geospatial-distance-multiplier>` section.

The following spherical proximity query, returns all documents in the
collection ``places`` within ``100`` miles from the point ``[ -74,
Expand Down Expand Up @@ -358,7 +384,84 @@ their distance from the ``[ -74, 40.74 ]`` point.
between ``-180`` inclusive, and ``180``, valid values for latitude
are between ``-90`` and ``90``.

.. TODO add in distanceMultiplier description
.. _geospatial-distance-multiplier:

Distance Multiplier
~~~~~~~~~~~~~~~~~~~

``distanceMultiplier`` is an option that will automatically
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

an option to what?

multiply distances in :term:`documents <document>` returned by the assigned
value.

The :option:`distanceMultiplier` is useful when working with :ref:`spherical queries
<geospatial-query-spherical>`. :ref:`Documents <document>` returned
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

only use the glossary reference the first time you use a term in a section.

from spherical queries can be multiplied from radians to distance, so there is no need
to perform the conversion in another function.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can be? should be? are?

given this presentation, I'm not sure what I should do.


:option:`distanceMultiplier` can be useful for multiplying distance
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not :option:

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can be or is?

can we make this information actionable for users?

values of result documents to match a particular view settings.

The following example uses ``distanceMultiplier`` in :dbcommand:`geoNear`
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in geoNear what?

with a :ref:`spherical <geospatial-query-spherical>` example:

.. code-block:: javascript

db.runCommand( { geoNear: "places",
near: [ -74, 40.74 ],
maxDistance: { 100 / 3963.192 },
spherical: true,
distanceMultiplier: 3963.192
} )

.. seealso::
:ref:`geospatial-query-distance`
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the foo section.


.. _geospatial-haystack-queries:

Querying Haystack Indexes
-------------------------

:ref:`Geospatial haystack indexes <geospatial-haystack-index>` are
useful to optimize your location data for certain ``bucketSize`` with
another field.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this needs to be reprhased a bit.


.. 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``.

To utilize the haystack indexes with your queries, you must use
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/ize//

the :dbcommand:`geoSearch` command with another field. The
:func:`find() <db.collection.find()>` and :dbcommand:`geoFind` will
not use the haystack index.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the find() and geoFind will

what are they?


The :dbcommand:`geoSearch` has the following prototype:
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

prototype form


.. code-block:: javascript

db.runCommand( { geoSearch: <haystack index>,
search: { <field>: <value> } } )

For example, to find all the ``restaurants`` within the pre-indexed ``bucketsize`` in
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bucketSize is conventionally camel cased, I think.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"pre-indexed" is not a common term that we use in relation to MongoDB. what is the concept you're trying to convey here?

the ``places`` collection near a particular point, the command would be:
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

to return all documents with the value resturants in the type field near the <ex> point

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

command would resemble:

OR

use the following command:


.. code-block:: javascript

db.runCommand( { geoSearch: "places",
search: { type: "restaurant" },
near: [-74, 40.74] } )


To create geospatial indexes with the haystack option and a particular
``bucketsize``, please see: :ref:`Haystack Index
<geospatial-haystack-index>`
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should probably go at the beginning of this section


.. note::

:ref:`Spherical queries <geospatial-spherical-representation>` are
not currently supported by haystack indexes.


Multi-location Documents
------------------------
Expand Down Expand Up @@ -418,7 +521,7 @@ coordinates. Consider the following prototype data model:
]
}

Then, create the geospatial index on the ``addresses.lock`` field as
Then, create the geospatial index on the ``addresses.loc`` field as
in the following example:

.. code-block:: javascript
Expand Down
Loading