Skip to content

Commit 92fd086

Browse files
authored
DOCSP-37004 - Indexes (#14)
1 parent 2c274cf commit 92fd086

File tree

2 files changed

+112
-89
lines changed

2 files changed

+112
-89
lines changed

source/fundamentals.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,10 @@ Fundamentals
1111
:titlesonly:
1212
:maxdepth: 1
1313

14+
/fundamentals/indexes
1415
/fundamentals/periodic-executors
1516
/fundamentals/type-hints
1617

18+
- :ref:`pymongo-indexes`
1719
- :ref:`pymongo-periodic-executors`
1820
- :ref:`pymongo-type-hints`

source/fundamentals/indexes.txt

Lines changed: 110 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,60 @@
1-
.. uses geo.rst
1+
.. _pymongo-indexes:
22

3-
Indexing
3+
Indexes
4+
=======
5+
6+
.. contents:: On this page
7+
:local:
8+
:backlinks: none
9+
:depth: 2
10+
:class: singlecol
11+
12+
.. facet::
13+
:name: genre
14+
:values: reference
15+
16+
.. meta::
17+
:keywords: query, location
18+
19+
Overview
420
--------
521

622
Adding indexes can help accelerate certain queries and can also add additional
7-
functionality to querying and storing documents. In this example, we'll
8-
demonstrate how to create a `unique index
9-
<http://mongodb.com/docs/manual/core/index-unique/>`_ on a key that rejects
10-
documents whose value for that key already exists in the index.
23+
functionality to querying and storing documents.
24+
25+
Unique Indexes
26+
--------------
1127

12-
First, we'll need to create the index:
28+
This section demonstrates how to create a
29+
:manual:`unique index </core/index-unique/>` on a key that
30+
rejects documents whose value for that key already exists in the index.
31+
32+
.. tip::
33+
34+
For more information about indexes, see the
35+
:manual:`MongoDB Server manual. </indexes/>`
36+
37+
The following code creates a unique index on the ``user_id`` field:
1338

1439
.. code-block:: python
1540

1641
>>> result = db.profiles.create_index([("user_id", pymongo.ASCENDING)], unique=True)
1742
>>> sorted(list(db.profiles.index_information()))
1843
['_id_', 'user_id_1']
1944

20-
Notice that we have two indexes now: one is the index on ``_id`` that MongoDB
21-
creates automatically, and the other is the index on ``user_id`` we just
22-
created.
45+
.. note::
46+
47+
MongoDB automatically creates an index on the ``_id`` field.
2348

24-
Now let's set up some user profiles:
49+
The following code creates two user profiles:
2550

2651
.. code-block:: python
2752

2853
>>> user_profiles = [{"user_id": 211, "name": "Luke"}, {"user_id": 212, "name": "Ziltoid"}]
2954
>>> result = db.profiles.insert_many(user_profiles)
3055

31-
The index prevents us from inserting a document whose ``user_id`` is already in
32-
the collection:
56+
A unique index prevents you from inserting a document whose value for the ``user_id``
57+
field is already in the collection:
3358

3459
.. code-block:: python
3560

@@ -40,116 +65,112 @@ the collection:
4065
Traceback (most recent call last):
4166
DuplicateKeyError: E11000 duplicate key error index: test_database.profiles.$user_id_1 dup key: { : 212 }
4267

43-
.. seealso:: The MongoDB documentation on `indexes <https://www.mongodb.com/docs/manual/indexes/>`_
44-
45-
Geospatial Indexing Example
46-
===========================
47-
48-
.. code-block:: python
49-
50-
from pymongo import MongoClient
51-
52-
client = MongoClient()
53-
client.drop_database("geo_example")
54-
55-
This example shows how to create and use a ``~pymongo.GEO2D``
56-
index in PyMongo. To create a spherical (earth-like) geospatial index use ``~pymongo.GEOSPHERE`` instead.
68+
Geospatial Indexes
69+
------------------
5770

58-
.. seealso:: The MongoDB documentation on `Geospatial Indexes <https://dochub.mongodb.org/core/geo>`_.
71+
This section shows how to create and use a ``~pymongo.GEO2D``
72+
index in PyMongo.
5973

60-
Creating a Geospatial Index
61-
---------------------------
62-
63-
Creating a geospatial index in pymongo is easy:
74+
The following code example shows how to create a geospatial index:
6475

6576
.. code-block:: python
6677

67-
>>> from pymongo import MongoClient, GEO2D
68-
>>> db = MongoClient().geo_example
69-
>>> db.places.create_index([("loc", GEO2D)])
70-
'loc_2d'
71-
72-
Inserting Places
73-
----------------
78+
>>> from pymongo import MongoClient, GEO2D
79+
>>> db = MongoClient().geo_example
80+
>>> db.places.create_index([("loc", GEO2D)])
81+
'loc_2d'
7482

7583
Locations in MongoDB are represented using either embedded documents
76-
or lists where the first two elements are coordinates. Here, we'll
77-
insert a couple of example locations:
84+
or lists where the first two elements are coordinates. The following code inserts
85+
four example locations into the geospatial index:
7886

7987
.. code-block:: python
8088

81-
>>> result = db.places.insert_many(
82-
... [{"loc": [2, 5]}, {"loc": [30, 5]}, {"loc": [1, 2]}, {"loc": [4, 4]}]
83-
... )
84-
>>> result.inserted_ids
85-
[ObjectId('...'), ObjectId('...'), ObjectId('...'), ObjectId('...')]
89+
>>> result = db.places.insert_many(
90+
... [{"loc": [2, 5]}, {"loc": [30, 5]}, {"loc": [1, 2]}, {"loc": [4, 4]}]
91+
... )
92+
>>> result.inserted_ids
93+
[ObjectId('...'), ObjectId('...'), ObjectId('...'), ObjectId('...')]
8694

87-
.. note:: If specifying latitude and longitude coordinates in ``~pymongo.GEOSPHERE``, list the **longitude** first and then **latitude**.
95+
.. tip::
8896

89-
Querying
90-
--------
97+
To create a spherical (earth-like) geospatial index, use ``~pymongo.GEOSPHERE`` instead.
98+
When specifying latitude and longitude coordinates in ``~pymongo.GEOSPHERE``,
99+
list the longitude first and the latitude second.
91100

92-
Using the geospatial index we can find documents near another point:
101+
After you create and populate the geospatial index, you can find documents near another
102+
point. The following example shows how to find documents near a location that has
103+
the coordinates ``3, 6``:
93104

94105
.. code-block:: python
95106

96-
>>> import pprint
97-
>>> for doc in db.places.find({"loc": {"$near": [3, 6]}}).limit(3):
98-
... pprint.pprint(doc)
99-
...
100-
{'_id': ObjectId('...'), 'loc': [2, 5]}
101-
{'_id': ObjectId('...'), 'loc': [4, 4]}
102-
{'_id': ObjectId('...'), 'loc': [1, 2]}
107+
>>> import pprint
108+
>>> for doc in db.places.find({"loc": {"$near": [3, 6]}}).limit(3):
109+
... pprint.pprint(doc)
110+
...
111+
{'_id': ObjectId('...'), 'loc': [2, 5]}
112+
{'_id': ObjectId('...'), 'loc': [4, 4]}
113+
{'_id': ObjectId('...'), 'loc': [1, 2]}
103114

104-
.. note:: If using ``pymongo.GEOSPHERE``, using $nearSphere is recommended.
115+
.. note::
116+
117+
If using ``pymongo.GEOSPHERE``, we recommend using the ``$nearSphere`` operator.
105118

106-
The $maxDistance operator requires the use of ``~bson.son.SON``:
119+
To use the ``$maxDistance`` operator, you must import the ``~bson.son.SON`` module:
107120

108121
.. code-block:: python
109122

110-
>>> from bson.son import SON
111-
>>> query = {"loc": SON([("$near", [3, 6]), ("$maxDistance", 100)])}
112-
>>> for doc in db.places.find(query).limit(3):
113-
... pprint.pprint(doc)
114-
...
115-
{'_id': ObjectId('...'), 'loc': [2, 5]}
116-
{'_id': ObjectId('...'), 'loc': [4, 4]}
117-
{'_id': ObjectId('...'), 'loc': [1, 2]}
123+
>>> from bson.son import SON
124+
>>> query = {"loc": SON([("$near", [3, 6]), ("$maxDistance", 100)])}
125+
>>> for doc in db.places.find(query).limit(3):
126+
... pprint.pprint(doc)
127+
...
128+
{'_id': ObjectId('...'), 'loc': [2, 5]}
129+
{'_id': ObjectId('...'), 'loc': [4, 4]}
130+
{'_id': ObjectId('...'), 'loc': [1, 2]}
118131

119132
It's also possible to query for all items within a given rectangle
120133
(specified by lower-left and upper-right coordinates):
121134

122135
.. code-block:: python
123136

124-
>>> query = {"loc": {"$within": {"$box": [[2, 2], [5, 6]]}}}
125-
>>> for doc in db.places.find(query).sort("_id"):
126-
... pprint.pprint(doc)
127-
...
128-
{'_id': ObjectId('...'), 'loc': [2, 5]}
129-
{'_id': ObjectId('...'), 'loc': [4, 4]}
137+
>>> query = {"loc": {"$within": {"$box": [[2, 2], [5, 6]]}}}
138+
>>> for doc in db.places.find(query).sort("_id"):
139+
... pprint.pprint(doc)
140+
...
141+
{'_id': ObjectId('...'), 'loc': [2, 5]}
142+
{'_id': ObjectId('...'), 'loc': [4, 4]}
130143

131-
Or circle (specified by center point and radius):
144+
Or a circle (specified by center point and radius):
132145

133146
.. code-block:: python
134147

135-
>>> query = {"loc": {"$within": {"$center": [[0, 0], 6]}}}
136-
>>> for doc in db.places.find(query).sort("_id"):
137-
... pprint.pprint(doc)
138-
...
139-
{'_id': ObjectId('...'), 'loc': [2, 5]}
140-
{'_id': ObjectId('...'), 'loc': [1, 2]}
141-
{'_id': ObjectId('...'), 'loc': [4, 4]}
148+
>>> query = {"loc": {"$within": {"$center": [[0, 0], 6]}}}
149+
>>> for doc in db.places.find(query).sort("_id"):
150+
... pprint.pprint(doc)
151+
...
152+
{'_id': ObjectId('...'), 'loc': [2, 5]}
153+
{'_id': ObjectId('...'), 'loc': [1, 2]}
154+
{'_id': ObjectId('...'), 'loc': [4, 4]}
142155

143-
geoNear queries are also supported using ``~bson.son.SON``:
156+
You can also use the ``~bson.son.SON`` module to run ``geoNear`` queries:
144157

145158
.. code-block:: python
146159

147-
>>> from bson.son import SON
148-
>>> db.command(SON([('geoNear', 'places'), ('near', [1, 2])]))
149-
{'ok': 1.0, 'stats': ...}
160+
>>> from bson.son import SON
161+
>>> db.command(SON([('geoNear', 'places'), ('near', [1, 2])]))
162+
{'ok': 1.0, 'stats': ...}
163+
164+
.. important::
165+
166+
The ``geoNear`` command is deprecated starting in MongoDB 4.0. Use one of the following
167+
operations instead:
150168

151-
.. warning:: Starting in MongoDB version 4.0, MongoDB deprecates the **geoNear** command. Use one of the following operations instead.
169+
* The ``$geoNear`` aggregation stage
170+
* The ``$near`` query operator
171+
* The ``$nearSphere`` query operator
152172

153-
* $geoNear - aggregation stage.
154-
* $near - query operator.
155-
* $nearSphere - query operator.
173+
.. tip::
174+
175+
For more information about geospatial indexes, see the
176+
:manual:`MongoDB Server manual. </core/indexes/index-types/index-geospatial/>`

0 commit comments

Comments
 (0)