Skip to content

Geo operators #99

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 16 commits into from
Closed
Show file tree
Hide file tree
Changes from all 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
6 changes: 2 additions & 4 deletions draft/applications/geospatial-indexes.txt
Original file line number Diff line number Diff line change
Expand Up @@ -208,8 +208,8 @@ Circles

To return results within the :ref:`bounds <geospatial-query-bounded>`
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:
using the :operator:`$within` operator and the :operator:`$center`
operator. Consider the following prototype query:

.. code-block:: javascript

Expand Down Expand Up @@ -362,8 +362,6 @@ 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

Multi-location Documents
------------------------

Expand Down
78 changes: 54 additions & 24 deletions source/reference/commands.txt
Original file line number Diff line number Diff line change
Expand Up @@ -934,44 +934,63 @@ Replication
Geospatial Commands
~~~~~~~~~~~~~~~~~~~

.. TODO read section outloud to self

.. dbcommand:: geoNear

The :dbcommand:`geoNear` command provides an alternative to the
:dbcommand:`$near` operator. In addition to the
functionality of :operator:`$near`, :dbcommand:`geoNear` returns the distance of
each item from the specified point along with additional diagnostic
information. For example:
:func:`db.collection.find()` method with :dbcommand:`$near`
operator. In addition to the functionality of :operator:`$near`,
:dbcommand:`geoNear` returns the distance of each item from the
specified point along with additional diagnostic information. The
following :dbcommand:`geoNear` example returns the 10 items nearest
to the coordinates ``[50,50]`` in the collection named ``places``.

.. code-block:: javascript

{ geoNear : "places" , near : [50,50], num : 10 }

Here, :dbcommand:`geoNear` returns the 10 items nearest to the
coordinates ``[50,50]`` in the collection named
``places``. `geoNear` provides the following options (specify all
distances in the same units as the document coordinate system:)
The :dbcommand:`geoNear` command provides the following options:

:field near: Takes the coordinates (e.g. ``[ x, y ]``) to use as
the center of a geospatial query.
:field coordinate near: Takes the coordinates (e.g. ``[ x, y ]``) to use as
the center of a geospatial query.

:field num: Specifies the maximum number of documents to return.

:field maxDistance: Limits the results to those falling within
a given distance of the center coordinate.
:field maxDistance: Limits the results to those within a given
distance of the center coordinate.

:field query: Further narrows the results using any standard
MongoDB query operator or selection. See :func:`db.collection.find()`
and ":doc:`/reference/operators`" for more
information.
MongoDB query operator or selection. See
:func:`db.collection.find()` and
":doc:`/reference/operators`" for more information.

:field distanceMultipler: Specifies a factor to multiply
all distances returned by
all distance fields returned by
:dbcommand:`geoNear`. For example, use
``distanceMultiplier`` to convert from
spherical queries returned in radians to
linear units (i.e. miles or kilometers)
by multiplying by the radius of the
Earth.
distance units.
.. TODO redo above...

:field boolean spherical: If set to ``true``, MongoDB will use
spherical geometry to calculate
distances. The default is ``false``,
MongoDB uses plane geometry to calculate
distances.

:field boolean uniqueDocs: If set to ``true``, a document will only
appear once in the result set, even if a
query matches :ref:`multiple location
fields <geospatial-query-multiple>` of
the document. The default is ``false``,
where a document may appear multiple
times in the result set.

:field boolean includeLocs: A boolean variable to include the
location field with the distance field
when using :ref:`Multi-location
documents <geospatial-multi-location>`.

Copy link
Contributor

Choose a reason for hiding this comment

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

this looks incomplete.

.. read-lock, slave-ok

Expand All @@ -980,21 +999,32 @@ Geospatial Commands
The :dbcommand:`geoSearch` command provides an interface to
MongoDB's :term:`haystack index` functionality. These indexes are
useful for returning results based on location coordinates *after*
collecting results based on some other query (i.e. a "haystack.")
collecting results based on another query (i.e. a "haystack.")
Consider the following example:

.. code-block:: javascript

{ geoSearch : "places", near : [33, 33], maxDistance : 6, search : { type : "restaurant" }, limit : 30 }
{ geoSearch: "places", near: [33, 33], search: { type: "restaurant" } }

The above command returns all documents with a ``type`` of
``restaurant`` having a maximum distance of 6 units from the
coordinates ``[30,33]`` in the collection ``places`` up to a
maximum of 30 results.
``restaurant`` near the coordinates ``[30,33]`` in the collection
``places``.

Unless specified otherwise, the :dbcommand:`geoSearch` command
limits results to 50 documents.

The :dbcommand:`geoSearch` command provides the following options:

:field near: Takes the coordinates (e.g. ``[ x, y ]``) to use as
the center of a geospatial query.

:field num: Specifies the maximum number of documents to return.

:field maxDistance: Limits the results to those falling within
a given distance of the center coordinate.

:field search: Specifies another field to query the haystack index.

.. read-lock, slave-ok

Collections
Expand Down
4 changes: 2 additions & 2 deletions source/reference/glossary.txt
Original file line number Diff line number Diff line change
Expand Up @@ -812,5 +812,5 @@ Glossary
ObjectId values as the default values for :term:`_id` fields.

Geohash
A value is a binary representation of the location on a
coordinate grid.
A value that is a binary representation of a location on a
coordinate grid. Used in MongoDB's geospatial index system.
124 changes: 89 additions & 35 deletions source/reference/operators.txt
Original file line number Diff line number Diff line change
Expand Up @@ -271,62 +271,116 @@ Geospatial
db.collection.find( { location: { $within: { shape } } } );

Replace ``{ shape }`` with a document that describes a shape. The
:operator:`$within` command supports three shapes. These shapes and the
relevant expressions follow:
:operator:`$within` operator supports three basic shape types. These
shapes are:

- Rectangles. Use the :operator:`$box` shape, consider the following
variable and :operator:`$within` document:
.. operator:: $box

.. code-block:: javascript
The :operator:`$box` operator specifies a rectangular shape for
the :operator:`$within` operator. To use the :operator:`$box`
operator, you must specify the bottom left and top right corners
of the rectangle in an array object. Consider the following
example:

db.collection.find( { location: { $within: { $box: [[100,0], [120,100]] } } } );
.. code-block:: javascript

db.collection.find( { loc: { $within: { $box: [ [0,0], [100,100] ] } } } )

This will return all the documents that are within the box
having points: ``[0,0]``, ``[0,100]``, ``[100,0]``, and ``[100,100]``.

.. operator:: $center
Copy link
Contributor

Choose a reason for hiding this comment

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

is it circle or center?

Copy link
Contributor

Choose a reason for hiding this comment

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

wiki says: center

I think the docs themselves need to be updated to reflect this point?

Copy link
Author

Choose a reason for hiding this comment

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

yes, command is $center

btw, I don't see this line in the current version... is this a comment on an earlier commit?

Copy link
Contributor

Choose a reason for hiding this comment

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

https://github.com/a-leung/mongodb-docs/blob/c2fda9f17af49cd182e4420fa2d2e276d4fdd5db/draft/applications/geospatial-indexes.txt#L239

That says circle. I'm not sure if the other geo documents make this mistake, but we should check...


This specifies a circle shape for the :operator:`$within`
operators. To define the bounds of a query using
:operator:`$center`, you must specify:

- the center point, and

- the radius

Here a box, ``[[100,120], [100,0]]`` describes the parameter
for the query. As a minimum, you must specify the lower-left and
upper-right corners of the box.
Considering the following example:

- Circles. Specify circles in the following form:
.. code-block:: javascript

db.collection.find( { location: { $within: { $center: [ [0,0], 10 } } } );

.. code-block:: javascript
The above command returns all the documents that fall within a
10 unit radius of the point ``[0,0]``.

db.collection.find( { location: { $within: { $circle: [ center, radius } } } );
.. operator:: $polygon

- Polygons. Specify polygons with an array of points. See the
following example:
Use :operator:`$polygon` to specify a polgon for a bounded query
using the :operator:`$within` operator. To define the polygon,
you must specify an array of coordinate points, as in the
following:

.. code-block:: javascript
[ [ x1,y1 ], [x2,y2], [x3,y3] ]

db.collection.find( { location: { $within: { $box: [[100,120], [100,100], [120,100], [240,200]] } } } );
The last point specified is always implicitly connected to the
first. You can specify as many points, and therfore sides, as
you like. Consider the following bounded query for documents
with coordinates within a polygon:

.. code-block:: javascript

The last point of a polygon is implicitly connected to the first
point.
db.collection.find( { loc: { $within: { $polygon: [ [0,0], [3,6], [6,0] ] } } } )

All shapes include the border of the shape as part of the shape,
although this is subject to the imprecision of floating point
numbers.
calculations.

.. operator:: $nearSphere

The :operator:`$nearSphere` operator is the spherical equivalent of
the :operator:`$near` operator. :operator:`$nearSphere` returns all
documents near a point, calculating distances using spherical geometry.

.. code-block:: javascript

db.collection.find( { loc: { $nearSphere: [0,0] } } )

.. operator:: $centerSphere

The :operator:`$centerSphere` operator is the spherical equivalent
of the :operator:`$center` operator. :operator:`$centerSphere` uses
spherical geometry to calculate distances in a circle specified by
a point and radius.

Considering the following example:

.. code-block:: javascript

db.collection.find( { loc: { $centerSphere: { [0,0], 10 / 3959 } } } )

This query will return all documents within a 10 mile radius of
``[0,0]`` using a spherical geometry to calculate distances.

.. operator:: $uniqueDocs

When using the :dbcommand:`geoNear`, if document contains more than
one field with coordinate values, MongoDB will return the same
document multiple times. When using the :operator:`$within`,
however, MongoDB provides opposite behavior: if a document contains
more than one field with coordinate values, MongoDB will only
return the document once.
.. TODO read aloud

The :operator:`$uniqueDocs` operator overrides these default
behaviors.
The :operator:`$uniqueDocs` operator overrides default query
behavior when :ref:`multiple location documents
<geospatial-query-multi-location>` are used.

By specifying ``$uniqueDocs: false`` in a :operator:`$within`
query, will cause the query to return a single document multiple
times if there is more than one match.
When querying multiple location documents using the
:operator:`$within` operator, MongoDB will return matching documents
once, even if there are multiple matches in the location fields.

By contrast, if you specify ``uniqueDocs: true`` as an option to
the a :dbcommand:`geoNear` command, then :dbcommand:`geoNear` only
returns a single document even if there are multiple matches.
By specifying ``$uniqueDocs: false`` in the :operator:`$within`
operator, matching documents may be returned multiple times if
there are multiple matches in the location field.

.. code-block:: javascript

db.places.find( { loc : { $within : { $center : [[0.5, 0.5], 20], $uniqueDocs : true } } } )

.. note::

You cannot specify :operator:`$uniqueDocs` with :operator:`$near`
or haystack queries.
You cannot specify :operator:`$uniqueDocs` with
:operator:`$near` or :dbcommand:`geoSearch` for :ref:`haystack
indexes <geospatial-haystack-index>`.

.. index:: query selectors; logical
.. _query-selectors-logical:
Expand Down