Skip to content

Commit 6fbd5f7

Browse files
authored
DOCSP-9555: indexes (#55)
* DOCSP-9555: indexes * addressing nits * more clarity * test comment delimit * adding more rst comments * code block formatting * more formatting * clarify that indexes support other operations * wording * indexes in toc tree * more nits * fixing extlinks * formatting fixes * clarifications * imports * monospace field names * monospace field names
1 parent 2619ede commit 6fbd5f7

File tree

3 files changed

+533
-1
lines changed

3 files changed

+533
-1
lines changed

source/fundamentals.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,12 +14,12 @@ Fundamentals
1414
/fundamentals/databases-collections
1515
/fundamentals/data-formats
1616
/fundamentals/crud
17+
/fundamentals/indexes
1718
/fundamentals/aggregation
1819

1920

2021
..
2122
/fundamentals/builders
22-
/fundamentals/indexes
2323
/fundamentals/collations
2424
/fundamentals/csfle
2525
/fundamentals/gridfs

source/fundamentals/indexes.txt

Lines changed: 373 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,373 @@
1+
=======
2+
Indexes
3+
=======
4+
5+
.. default-domain:: mongodb
6+
7+
.. contents:: On this page
8+
:local:
9+
:backlinks: none
10+
:depth: 2
11+
:class: singlecol
12+
13+
.. common-content-begin
14+
15+
Overview
16+
--------
17+
18+
Indexes support the efficient execution of queries in MongoDB. Without indexes, MongoDB must scan *every* document in a
19+
collection (a **collection scan**) to find the documents that match each query. These collection scans are slow and can
20+
negatively affect the performance of your application. If an appropriate index exists for a query, MongoDB can use the
21+
index to limit the number of documents it must inspect.
22+
23+
Indexes also:
24+
25+
- allow efficient sorting
26+
- enable special capabilities like :ref:`geospatial <geo-indexes>` search
27+
- allow adding constraints to ensure a field value is :ref:`unique <unique-indexes>`
28+
- and :manual:`more </indexes/>`
29+
30+
.. tip::
31+
32+
Indexes are also used by update operations when finding the document(s) to update, delete operations when finding the
33+
document(s) to delete, and by :manual:`certain stages </core/aggregation-pipeline/#pipeline-operators-and-indexes>` in
34+
the aggregation framework.
35+
36+
Query Coverage and Performance
37+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
38+
39+
When you execute a query against MongoDB, your command can include various elements:
40+
41+
- query criteria that specify field(s) and value(s) you are looking for
42+
- options that affect the query's execution (e.g. read concern)
43+
- projection criteria to specify the fields MongoDB should return (optional)
44+
- sort criteria to specify the order documents will be returned from MongoDB (optional)
45+
46+
When all the fields specified in the query, projection, and sort are in the same index, MongoDB returns results directly
47+
from the index, also called a **covered query**.
48+
49+
.. important:: Sort Order
50+
51+
Sort criteria must match or invert the order of the index.
52+
53+
Consider an index on the field ``name`` in ascending order (A-Z), ``age`` in descending order (9-0):
54+
55+
.. code-block:: none
56+
:copyable: false
57+
58+
name_1_age_-1
59+
60+
MongoDB would use this index when you sort your data by either:
61+
62+
- ``name`` ascending, ``age`` descending
63+
- ``name`` descending, ``age`` ascending
64+
65+
Specifying a sort order of ``name`` and :guilabel:`age` ascending or :guilabel:`name` and ``age``
66+
descending would require an in-memory sort.
67+
68+
For additional information on how to ensure your index covers your query criteria and projection, see the MongoDB manual
69+
articles on :manual:`query coverage </core/query-optimization/#read-operations-covered-query>`.
70+
71+
Operational Considerations
72+
~~~~~~~~~~~~~~~~~~~~~~~~~~
73+
74+
To improve query performance, build indexes on fields that appear often in your application's queries and operations
75+
that return sorted results. Each index that you add consumes disk space and memory when active so you should track index
76+
memory and disk usage for capacity planning. In addition, when a write operation updates an indexed field, MongoDB also
77+
has to update the related index.
78+
79+
Since MongoDB supports dynamic schemas, applications can query against fields whose names cannot be known in advance or
80+
are arbitrary. MongoDB 4.2 introduced :manual:`wildcard indexes </core/index-wildcard/>` to help support these queries.
81+
Wildcard indexes are not designed to replace workload-based index planning.
82+
83+
For more information on designing your data model and choosing indexes appropriate for your application, see the MongoDB
84+
server documentation on :manual:`Indexing Strategies </applications/indexes>` and
85+
:manual:`Data Modeling and Indexes </core/data-model-operations/#data-model-indexes>`.
86+
87+
Index Types
88+
-----------
89+
90+
MongoDB supports a number of different index types to support querying your data. The following sections describe the
91+
most common index types and provide sample code for creating each index type. For a full list of index types, see
92+
:manual:`Indexes </indexes/>`.
93+
94+
.. common-content-end
95+
96+
.. driver-content-begin
97+
98+
.. tip::
99+
100+
The MongoDB Java Driver provides the :java-core-api:`Indexes </com/mongodb/client/model/Indexes.html>` class that
101+
includes static factory methods to create index specification documents for different MongoDB Index key types.
102+
103+
The following examples use the
104+
:java-sync-api:`createIndex </com/mongodb/client/MongoCollection.html#createIndex(org.bson.conversions.Bson,com.mongodb.client.model.IndexOptions)>`
105+
to create various indexes, and the following setup:
106+
107+
.. literalinclude:: /includes/fundamentals/code-snippets/IndexPage.java
108+
:language: java
109+
:dedent:
110+
:start-after: begin imports
111+
:end-before: end imports
112+
113+
114+
.. literalinclude:: /includes/fundamentals/code-snippets/IndexPage.java
115+
:language: java
116+
:dedent:
117+
:start-after: begin declaration
118+
:end-before: end declaration
119+
120+
.. driver-content-end
121+
122+
.. common-content-begin
123+
124+
Single Field and Compound Indexes
125+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
126+
127+
Single Field Indexes
128+
++++++++++++++++++++
129+
130+
:manual:`Single field indexes </core/index-single/>` are indexes with a reference to a single field within a collection's
131+
documents. They improve single field query and sort performance, and support :manual:`TTL Indexes </core/index-ttl>` that
132+
automatically remove documents from a collection after a certain amount of time or at a specific clock time.
133+
134+
135+
.. note::
136+
137+
The ``_id_`` index is an example of a single field index. This index is automatically created on the ``_id`` field
138+
when a new collection is created.
139+
140+
The following example creates an index in ascending order on the ``title`` field:
141+
142+
.. common-content-end
143+
144+
.. driver-content-begin
145+
.. literalinclude:: /includes/fundamentals/code-snippets/IndexPage.java
146+
:language: java
147+
:dedent:
148+
:start-after: begin single index
149+
:end-before: end single index
150+
.. driver-content-end
151+
152+
The following is an example of a query that would be covered by the index created above:
153+
154+
.. driver-content-begin
155+
.. literalinclude:: /includes/fundamentals/code-snippets/IndexPage.java
156+
:language: java
157+
:dedent:
158+
:start-after: begin covered single query
159+
:end-before: end covered single query
160+
.. driver-content-end
161+
162+
.. common-content-begin
163+
164+
See the MongoDB server manual section on :manual:`single field indexes </core/index-single>` for more information.
165+
166+
Compound Indexes
167+
++++++++++++++++
168+
169+
:manual:`Compound </core/index-compound/>` indexes hold references to multiple fields within a collection's documents,
170+
improving query and sort performance.
171+
172+
.. tip::
173+
174+
Read more about compound indexes, **index prefixes**, and sort order :manual:`here </core/index-compound/#prefixes>`.
175+
176+
The following example creates a compound index on the ``type`` and ``rated`` fields:
177+
178+
.. common-content-end
179+
180+
.. driver-content-begin
181+
182+
.. literalinclude:: /includes/fundamentals/code-snippets/IndexPage.java
183+
:language: java
184+
:dedent:
185+
:start-after: begin compound index
186+
:end-before: end compound index
187+
188+
The following is an example of a query that would be covered by the index created above:
189+
190+
.. literalinclude:: /includes/fundamentals/code-snippets/IndexPage.java
191+
:language: java
192+
:dedent:
193+
:start-after: begin covered compound query
194+
:end-before: end covered compound query
195+
.. driver-content-end
196+
197+
.. common-content-begin
198+
199+
See the MongoDB server manual section on :manual:`Compound indexes </core/index-compound>` for more information.
200+
201+
Multikey Indexes (Indexes on Array Fields)
202+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
203+
204+
**Multikey indexes** are indexes that improve performance for queries that specify a field with an index that contains
205+
an array value. You can define a multikey index using the same syntax as a single field or compound index.
206+
207+
The following example creates a compound, multikey index on the ``rated`, ``genres`` (an array of
208+
Strings), and ``title`` fields:
209+
210+
.. common-content-end
211+
.. driver-content-begin
212+
.. literalinclude:: /includes/fundamentals/code-snippets/IndexPage.java
213+
:language: java
214+
:dedent:
215+
:start-after: begin multikey index
216+
:end-before: end multikey index
217+
218+
The following is an example of a query that would be covered by the index created above:
219+
220+
.. literalinclude:: /includes/fundamentals/code-snippets/IndexPage.java
221+
:language: java
222+
:dedent:
223+
:start-after: begin covered multikey query
224+
:end-before: end covered multikey query
225+
.. driver-content-end
226+
227+
.. common-content-begin
228+
229+
Multikey indexes behave differently from non-multikey indexes in terms of query coverage, index bound computation, and
230+
sort behavior. For a full explanation of multikey indexes, including a discussion of their behavior and limitations,
231+
refer to the :manual:`Multikey Indexes page </core/index-multikey>` in the MongoDB manual.
232+
233+
Text Indexes
234+
~~~~~~~~~~~~
235+
236+
**Text indexes** support text search queries on string content. These indexes can include any field whose value is a
237+
string or an array of string elements. MongoDB supports text search for various languages. You can specify the default
238+
language as an option when creating the index.
239+
240+
.. tip::
241+
242+
Text indexes differ from the more powerful :atlas:`Atlas full text search indexes </atlas-search/>` Atlas users
243+
should use Atlas search.
244+
245+
.. warning::
246+
247+
Collections are limited to one text index. Keep in mind that a text index can cover multiple fields.
248+
249+
.. common-content-end
250+
251+
.. driver-content-begin
252+
253+
The following example creates a text index on the ``plot`` field:
254+
255+
.. literalinclude:: /includes/fundamentals/code-snippets/IndexPage.java
256+
:language: java
257+
:dedent:
258+
:start-after: begin text index
259+
:end-before: end text index
260+
261+
The following is an example of a query that would use the index created above. Note that the ``sort`` is
262+
omitted because text indexes do not contain sort order.
263+
264+
.. literalinclude:: /includes/fundamentals/code-snippets/IndexPage.java
265+
:language: java
266+
:dedent:
267+
:start-after: begin text query
268+
:end-before: end text query
269+
270+
.. driver-content-end
271+
.. common-content-begin
272+
273+
For a full explanation of text search with MongoDB, refer to :manual:`Text Indexes </core/index-text>` in the MongoDB
274+
manual.
275+
276+
Geospatial Indexes
277+
~~~~~~~~~~~~~~~~~~
278+
279+
.. _geo-indexes:
280+
281+
MongoDB supports queries of geospatial coordinate data using **2dsphere indexes**. With a 2dsphere index, you can query
282+
the geospatial data for inclusion, intersection, and proximity. For more information on querying geospatial data, see
283+
:manual:`Geospatial Queries </geospatial-queries/>`.
284+
285+
To create a 2dsphere index, you must specify a field that contains only **GeoJSON objects**. For more details on this
286+
type, see the MongoDB server manual page on :manual:`GeoJSON objects </reference/geojson>`.
287+
288+
The ``location.geo` field in following sample document from the ``theaters`` collection in the ``sample_mflix```
289+
database is a GeoJSON Point object that describes the coordinates of the theater:
290+
291+
.. code-block:: javascript
292+
293+
{
294+
"_id" : ObjectId("59a47286cfa9a3a73e51e75c"),
295+
"theaterId" : 104,
296+
"location" : {
297+
"address" : {
298+
"street1" : "5000 W 147th St",
299+
"city" : "Hawthorne",
300+
"state" : "CA",
301+
"zipcode" : "90250"
302+
},
303+
"geo" : {
304+
"type" : "Point",
305+
"coordinates" : [
306+
-118.36559,
307+
33.897167
308+
]
309+
}
310+
}
311+
}
312+
313+
The following example creates a ``2dsphere`` index on the ``location.geo`` field:
314+
315+
.. warning::
316+
317+
Attemping to create a geospatial index on a field that is covered by a geospatial index will result in an error.
318+
319+
.. common-content-end
320+
.. driver-content-begin
321+
322+
.. literalinclude:: /includes/fundamentals/code-snippets/IndexPage.java
323+
:language: java
324+
:dedent:
325+
:start-after: begin geospatial index
326+
:end-before: end geospatial index
327+
328+
The following is an example of a geospatial query using the "location.geo" index.
329+
330+
.. literalinclude:: /includes/fundamentals/code-snippets/IndexPage.java
331+
:language: java
332+
:dedent:
333+
:start-after: begin geospatial query
334+
:end-before: end geospatial query
335+
336+
.. driver-content-end
337+
.. common-content-begin
338+
339+
MongoDB also supports ``2d`` indexes for calculating distances on a Euclidean plane and for working with the "legacy
340+
coordinate pairs" syntax used in MongoDB 2.2 and earlier. See the :manual:`Geospatial Queries page </geospatial-queries>`
341+
in the MongoDB server manual for more further information.
342+
343+
Unique Indexes
344+
~~~~~~~~~~~~~~
345+
346+
.. _unique-indexes:
347+
348+
Unique indexes ensure that the indexed fields do not store duplicate values. By default, MongoDB creates a unique index
349+
on the ``_id`` field during the creation of a collection. To create a unique index, specify the field or combination of
350+
fields that you want to prevent duplication on and set the ``unique`` option to ``true``.
351+
352+
The following example creates a unique, descending index on the ``theaterId`` field:
353+
354+
.. common-content-end
355+
.. driver-content-begin
356+
357+
.. literalinclude:: /includes/fundamentals/code-snippets/IndexPage.java
358+
:language: java
359+
:dedent:
360+
:start-after: begin unique index
361+
:end-before: end unique index
362+
363+
.. warning::
364+
365+
Attempting to perform a write operation that stores a duplicate value that violates the unique index, the MongoDB
366+
Java driver will raise a ``DuplicateKeyException``, and MongoDB will throw an error resembling the following:
367+
368+
.. code-block:: none
369+
370+
E11000 duplicate key error index
371+
372+
Refer to the :manual:`Unique Indexes page </core/index-unique>` in the MongoDB server manual for more information.
373+
.. driver-content-end

0 commit comments

Comments
 (0)