Skip to content

Commit 31f3ce8

Browse files
(DOCSP-30364): Clarification for optimized pipeline (#6627) (#6646)
* (DOCSP-30364): Clarification for optimized pipeline * edit * remove admonition * nit * remove and/or * edits * add line highlights * reorder * review fixes
1 parent 181954f commit 31f3ce8

File tree

1 file changed

+56
-40
lines changed

1 file changed

+56
-40
lines changed

source/core/aggregation-pipeline-optimization.txt

Lines changed: 56 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -50,47 +50,58 @@ Pipeline Sequence Optimization
5050
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
5151

5252
For an aggregation pipeline that contains a projection stage
53-
(:pipeline:`$project` or :pipeline:`$unset` or
54-
:pipeline:`$addFields` or :pipeline:`$set`) followed by a
55-
:pipeline:`$match` stage, MongoDB moves any filters in the
56-
:pipeline:`$match` stage that do not require values computed in the
57-
projection stage to a new :pipeline:`$match` stage before the
53+
(:pipeline:`$addFields`, :pipeline:`$project`, :pipeline:`$set`, or
54+
:pipeline:`$unset`) followed by a :pipeline:`$match` stage, MongoDB
55+
moves any filters in the ``$match`` stage that do not require values
56+
computed in the projection stage to a new ``$match`` stage before the
5857
projection.
5958

60-
If an aggregation pipeline contains multiple projection and/or
61-
:pipeline:`$match` stages, MongoDB performs this optimization for each
62-
:pipeline:`$match` stage, moving each :pipeline:`$match` filter before
63-
all projection stages that the filter does not depend on.
59+
If an aggregation pipeline contains multiple projection or ``$match``
60+
stages, MongoDB performs this optimization for each ``$match`` stage,
61+
moving each ``$match`` filter before all projection stages that the
62+
filter does not depend on.
6463

65-
Consider a pipeline of the following stages:
64+
Consider a pipeline with the following stages:
6665

6766
.. code-block:: javascript
68-
:emphasize-lines: 9-14
67+
:emphasize-lines: 18-23
6968

70-
{ $addFields: {
71-
maxTime: { $max: "$times" },
72-
minTime: { $min: "$times" }
73-
} },
74-
{ $project: {
75-
_id: 1, name: 1, times: 1, maxTime: 1, minTime: 1,
76-
avgTime: { $avg: ["$maxTime", "$minTime"] }
77-
} },
78-
{ $match: {
79-
name: "Joe Schmoe",
80-
maxTime: { $lt: 20 },
81-
minTime: { $gt: 5 },
82-
avgTime: { $gt: 7 }
83-
} }
84-
85-
The optimizer breaks up the :pipeline:`$match` stage into four
86-
individual filters, one for each key in the :pipeline:`$match` query
87-
document. The optimizer then moves each filter before as many projection
88-
stages as possible, creating new :pipeline:`$match` stages as needed.
89-
Given this example, the optimizer produces the following *optimized*
90-
pipeline:
69+
{
70+
$addFields: {
71+
maxTime: { $max: "$times" },
72+
minTime: { $min: "$times" }
73+
}
74+
},
75+
{
76+
$project: {
77+
_id: 1,
78+
name: 1,
79+
times: 1,
80+
maxTime: 1,
81+
minTime: 1,
82+
avgTime: { $avg: ["$maxTime", "$minTime"] }
83+
}
84+
},
85+
{
86+
$match: {
87+
name: "Joe Schmoe",
88+
maxTime: { $lt: 20 },
89+
minTime: { $gt: 5 },
90+
avgTime: { $gt: 7 }
91+
}
92+
}
93+
94+
The optimizer breaks up the ``$match`` stage into four individual
95+
filters, one for each key in the ``$match`` query document. The
96+
optimizer then moves each filter before as many projection stages as
97+
possible, creating new ``$match`` stages as needed.
98+
99+
Given this example, the optimizer automatically produces the following
100+
*optimized* pipeline:
91101

92102
.. code-block:: javascript
93103
:emphasize-lines: 1, 6, 11
104+
:copyable: false
94105

95106
{ $match: { name: "Joe Schmoe" } },
96107
{ $addFields: {
@@ -104,6 +115,14 @@ pipeline:
104115
} },
105116
{ $match: { avgTime: { $gt: 7 } } }
106117

118+
.. note::
119+
120+
The optimized pipeline is not intended to be run manually. The
121+
original and optimized pipelines return the same results.
122+
123+
You can see the optimized pipeline in the :ref:`explain plan
124+
<example-aggregate-method-explain-option>`.
125+
107126
The :pipeline:`$match` filter ``{ avgTime: { $gt: 7 } }`` depends on the
108127
:pipeline:`$project` stage to compute the ``avgTime`` field. The
109128
:pipeline:`$project` stage is the last projection stage in this
@@ -121,13 +140,10 @@ use any values computed in either the :pipeline:`$project` or
121140
:pipeline:`$addFields` stages so it was moved to a new
122141
:pipeline:`$match` stage before both of the projection stages.
123142

124-
.. note::
125-
After optimization, the filter ``{ name: "Joe Schmoe" }`` is in
126-
a :pipeline:`$match` stage at the beginning of the pipeline. This has
127-
the added benefit of allowing the aggregation to use an index on the
128-
``name`` field when initially querying the collection.
129-
See :ref:`aggregation-pipeline-operators-and-performance` for more
130-
information.
143+
After optimization, the filter ``{ name: "Joe Schmoe" }`` is in a
144+
:pipeline:`$match` stage at the beginning of the pipeline. This has the
145+
added benefit of allowing the aggregation to use an index on the
146+
``name`` field when initially querying the collection.
131147

132148
.. _agg-sort-match-optimization:
133149

@@ -505,4 +521,4 @@ MongoDB increases the :pipeline:`$limit` amount with the reordering.
505521
.. seealso::
506522

507523
:method:`explain <db.collection.aggregate()>` option in the
508-
:method:`db.collection.aggregate()`
524+
:method:`db.collection.aggregate()`

0 commit comments

Comments
 (0)