Skip to content

Commit 1a5d72e

Browse files
author
Sam Kleinman
committed
merge: DOCS-956 with some edits
2 parents 8955c4e + 8c04f8b commit 1a5d72e

File tree

4 files changed

+190
-50
lines changed

4 files changed

+190
-50
lines changed

source/applications/indexes.txt

Lines changed: 93 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -117,32 +117,99 @@ can support all the queries that search a "prefix" subset of those fields.
117117
Create Indexes that Support Covered Queries
118118
-------------------------------------------
119119

120-
A covered index query is a query in which all the queried fields are
121-
part of an index. They are "covered queries" because an index "covers" the query.
122-
MongoDB can fulfill the query by using *only* the index. MongoDB need
123-
not scan documents from the database.
124-
125-
Querying *only* the index is much faster than querying documents. Index
126-
keys are typically smaller than the documents they catalog, and indexes
127-
are typically stored in RAM or located sequentially on disk.
128-
129-
Mongod automatically uses a covered query when possible. To ensure use
130-
of a covered query, create an index that includes all the fields listed
131-
in the query result. This means that the :term:`projection` document
132-
given to a query (to specify which fields MongoDB returns from
133-
the result set) must
134-
explicitly exclude the ``_id`` field from the result set, unless the
135-
index includes ``_id``.
136-
137-
MongoDB cannot use a covered query if any of the indexed fields in any
138-
of the documents in the collection includes an array. If an indexed field
139-
is an array, the index becomes a :ref:`multi-key index
140-
<index-type-multikey>` index and cannot support a covered query.
141-
142-
To test whether MongoDB used a covered query, use
143-
:method:`explain() <cursor.explain()>`. If the output displays ``true``
144-
for the ``indexOnly`` field, MongoDB used a covered query. For
145-
more information see :ref:`indexes-measuring-use`.
120+
A covered query is a query in which:
121+
122+
- all the fields in the :ref:`query <read-operations-query-document>`
123+
are part of an index, **and**
124+
125+
- all the fields returned in the results are in the same index.
126+
127+
Because the index "covers" the query, MongoDB can both match the
128+
:ref:`query conditions <read-operations-query-document>` **and** return
129+
the results using only the index; MongoDB does not need to look at
130+
the documents, only the index, to fulfill the query.
131+
132+
Querying *only* the index can be much faster than querying documents
133+
outside of the index. Index keys are typically smaller than the
134+
documents they catalog, and indexes are typically available in RAM or
135+
located sequentially on disk.
136+
137+
MongoDB automatically uses an index that covers a query when possible.
138+
To ensure that a query is covered, create an index that includes all
139+
the fields listed in the query result and the :ref:`query document
140+
<read-operations-query-document>`. This means that if the index does
141+
**not** include the ``_id`` field, the :term:`projection` document,
142+
which specifies the fields MongoDB returns, must explicitly exclude the
143+
``_id`` field from the result set.
144+
145+
Consider the following example where the collection ``user`` has
146+
an index on the fields ``user`` and ``status``:
147+
148+
.. code-block:: javascript
149+
150+
{ status: 1, user: 1 }
151+
152+
Then, the following query which queries on the ``status`` field and
153+
returns only the ``user`` field is covered:
154+
155+
.. code-block:: javascript
156+
157+
db.users.find( { status: "A" }, { user: 1, _id: 0 } )
158+
159+
However, the following query that uses the index to match documents is
160+
**not** covered by the index because it returns both the ``user`` field
161+
**and** the ``_id`` field:
162+
163+
.. code-block:: javascript
164+
165+
db.users.find( { status: "A" }, { user: 1 } )
166+
167+
An index **cannot** cover a query if:
168+
169+
- any of the indexed fields in any of the documents in the collection
170+
includes an array. If an indexed field is an array, the index becomes
171+
a :ref:`multi-key index <index-type-multikey>` index and cannot
172+
support a covered query.
173+
174+
- any of the indexed fields are fields in subdocuments. To index fields
175+
in subdocuments, use :term:`dot notation`. For example, consider
176+
a collection ``users`` with documents of the following form:
177+
178+
.. code-block:: javascript
179+
180+
{ _id: 1, user: { login: "tester" } }
181+
182+
The collection has the following indexes:
183+
184+
.. code-block:: none
185+
186+
{ user: 1 }
187+
188+
{ "user.login": 1 }
189+
190+
The ``{ user: 1 }`` index covers the following query:
191+
192+
.. code-block:: none
193+
194+
db.users.find( { user: { login: "tester" } }, { user: 1, _id: 0 } )
195+
196+
However, the ``{ "user.login": 1 }`` index does **not** cover the
197+
following query:
198+
199+
.. code-block:: none
200+
201+
db.users.find( { "user.login": "tester" }, { "user.login": 1, _id: 0 } )
202+
203+
The query, however, does use the ``{ "user.login": 1 }`` index to
204+
find matching documents.
205+
206+
To determine whether a query is a covered query, use the
207+
:method:`~cursor.explain()` method. If the :method:`~cursor.explain()`
208+
output displays ``true`` for the :data:`indexOnly` field, the query is
209+
covered by an index, and MongoDB queries only that index to match the
210+
query **and** return the results.
211+
212+
For more information see :ref:`indexes-measuring-use`.
146213

147214
.. _index-sort:
148215
.. _sorting-with-indexes:

source/core/indexes.txt

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,22 @@ MongoDB indexes have the following core features:
4646
with the best response time for each query type. You can override
4747
the query optimizer using the :method:`cursor.hint()` method.
4848

49-
- An index "covers" a query if the index keys store all the data that
50-
the query must return. When an index covers a query, the database
51-
returns results more quickly than for queries that have to scan many
52-
individual documents. See :ref:`indexes-covered-queries` for more
53-
information.
49+
- An index "covers" a query if:
50+
51+
- all the fields in the :ref:`query <read-operations-query-document>`
52+
are part of that index, **and**
53+
54+
- all the fields returned in the documents that match the query are
55+
in the same index.
56+
57+
When an index covers a query, the server can both match the
58+
:ref:`query conditions <read-operations-query-document>` **and**
59+
return the results using only the index; MongoDB does not need to
60+
look at the documents, only the index, to fulfill the query.
61+
Querying the index can be faster than querying the documents outside
62+
of the index.
63+
64+
See :ref:`indexes-covered-queries` for more information.
5465

5566
- Using queries with good index coverage reduces the number of full
5667
documents that MongoDB needs to store in memory, thus maximizing database

source/core/read-operations.txt

Lines changed: 56 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -354,9 +354,9 @@ Result Projections
354354
~~~~~~~~~~~~~~~~~~
355355

356356
The :term:`projection` specification limits the fields to return for
357-
all matching documents. Constraining the result set by restricting the
358-
fields to return can minimize network transit costs and the costs of
359-
deserializing documents in the application layer.
357+
all matching documents. Restricting the fields to return can minimize
358+
network transit costs and the costs of deserializing documents in the
359+
application layer.
360360

361361
The second argument to the :method:`find() <db.collection.find()>`
362362
method is a projection, and it takes the form of a :term:`document` with
@@ -458,6 +458,52 @@ operation:
458458
<index-ascending-and-descending>` to support sort operations in
459459
compound queries.
460460

461+
.. _read-operations-covered-query:
462+
463+
Covering a Query
464+
~~~~~~~~~~~~~~~~
465+
466+
An index :ref:`covers <indexes-covered-queries>` a query, a *covered
467+
query*, when:
468+
469+
- all the fields in the :ref:`query <read-operations-query-document>`
470+
are part of that index, **and**
471+
472+
- all the fields returned in the documents that match the query are in
473+
the same index.
474+
475+
For these queries, MongoDB does not need to inspect at documents
476+
outside of the index, which is often more efficient than inspecting
477+
entire documents.
478+
479+
.. example::
480+
481+
Given a collection ``inventory`` with the following index on the
482+
``type`` and ``item`` fields:
483+
484+
.. code-block:: sh
485+
486+
{ type: 1, item: 1 }
487+
488+
This index will cover the following query on the ``type`` and ``item``
489+
fields, which returns only the ``item`` field:
490+
491+
.. code-block:: javascript
492+
493+
db.inventory.find( { type: "food", item:/^c/ },
494+
{ item: 1, _id: 0 } )
495+
496+
However, this index will **not** cover the following query, which
497+
returns the ``item`` field **and** the ``_id`` field:
498+
499+
.. code-block:: javascript
500+
501+
db.inventory.find( { type: "food", item:/^c/ },
502+
{ item: 1 } )
503+
504+
See :ref:`indexes-covered-queries` for more information on the
505+
behavior and use of covered queries.
506+
461507
Measuring Index Use
462508
~~~~~~~~~~~~~~~~~~~
463509

@@ -552,9 +598,13 @@ the query used an index. This query:
552598
- then read 5 full documents from the collection, as indicated by
553599
the :data:`~explain.nscannedObjects` field.
554600

555-
This indicates that the query was not "covered," or able to complete
556-
only using the index, as reflected in the :data:`~explain.indexOnly`. See
557-
:ref:`indexes-covered-queries` for more information.
601+
Although the query uses an index to find the matching documents, if
602+
:data:`~explain.indexOnly` is false then an index could
603+
not :ref:`cover <read-operations-covered-query>` the query:
604+
MongoDB could not both match the :ref:`query conditions
605+
<read-operations-query-document>` **and** return the results using
606+
only this index. See :ref:`indexes-covered-queries` for more
607+
information.
558608

559609
.. index:: query optimizer
560610
.. _read-operations-query-optimization:

source/reference/explain.txt

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -154,18 +154,23 @@ Core Explain Output
154154

155155
.. data:: explain.nscannedObjects
156156

157-
:data:`~explain.nscannedObjects` is a number that reflects the total
158-
number of documents scanned during the query. The
159-
:data:`~explain.nscannedObjects` may be lower than :data:`~explain.nscanned`, such as
160-
if the index is a covered index.
157+
Specifies the total number of documents scanned during the query.
158+
The :data:`~explain.nscannedObjects` may be lower than
159+
:data:`~explain.nscanned`, such as if the index :ref:`covers
160+
<indexes-covered-queries>` a query. See
161+
:data:`~explain.indexOnly`. Additionally, the
162+
:data:`~explain.nscannedObjects` may be lower than
163+
:data:`~explain.nscanned` in the case of multikey index on an array
164+
field with duplicate documents.
161165

162166
.. data:: explain.nscanned
163167

164-
:data:`~explain.nscanned` is a number that reflects the total number of
165-
documents or index entries scanned during the database operation.
166-
Ideally the :data:`~explain.n` and :data:`~explain.nscanned` values should be as
167-
close as possible. The :data:`~explain.nscanned` value may be higher than
168-
the :data:`~explain.nscannedObjects` value, if the index is a covered index.
168+
Specifies the total number of documents or index entries scanned
169+
during the database operation. You want :data:`~explain.n` and
170+
:data:`~explain.nscanned` to be close in value as possible. The
171+
:data:`~explain.nscanned` value may be higher than the
172+
:data:`~explain.nscannedObjects` value, such as if the index :ref:`covers
173+
<indexes-covered-queries>` a query. See :data:`~explain.indexOnly`.
169174

170175
.. data:: explain.nscannedObjectsAllPlans
171176

@@ -196,10 +201,17 @@ Core Explain Output
196201

197202
.. data:: explain.indexOnly
198203

199-
:data:`~explain.indexOnly` is a boolean that is ``true`` when the
200-
query is :ref:`covered <indexes-covered-queries>` by the index. In
201-
*covered* queries, the index contains all data that MongoDB needs
202-
to fulfill the query.
204+
:data:`~explain.indexOnly` is a boolean value that returns ``true``
205+
when the the query is :ref:`covered <indexes-covered-queries>` by
206+
the index indicated in the :data:`~explain.cursor` field. When an
207+
index covers a query, MongoDB can both match the :ref:`query
208+
conditions <read-operations-query-document>` **and** return the
209+
results using only the index because:
210+
211+
- all the fields in the :ref:`query
212+
<read-operations-query-document>` are part of that index, **and**
213+
214+
- all the fields returned in the results set are in the same index.
203215

204216
.. data:: explain.nYields
205217

0 commit comments

Comments
 (0)