Skip to content

Commit 7b56365

Browse files
committed
DOCS-1105 sort w limit and other optimization
1 parent 12f6792 commit 7b56365

File tree

5 files changed

+100
-6
lines changed

5 files changed

+100
-6
lines changed

source/applications/aggregation.txt

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,83 @@ affecting the result. However, at this time place
236236
:agg:pipeline:`$match` operators at the beginning of the pipeline when
237237
possible.
238238

239+
Pipeline Sequence Optimization
240+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
241+
242+
.. versionchanged:: 2.4
243+
244+
:term:`Aggregation` operations have an optimization phase which
245+
attempts to re-arrange the pipeline for improved performance.
246+
247+
``$sort`` + ``$skip`` + ``$limit`` Sequence Optimization
248+
````````````````````````````````````````````````````````
249+
250+
When you have sequence of :agg:pipeline:`$sort` followed by a
251+
:agg:pipeline:`$skip` followed by a :agg:pipeline:`$limit`, an
252+
optimization occurs whereby the :agg:pipeline:`$limit` moves in front
253+
of the :agg:pipeline:`$skip`. For example, if the pipeline consists of
254+
the following stages:
255+
256+
.. code-block:: javascript
257+
258+
{ $sort: { age : -1 } },
259+
{ $skip: 10 },
260+
{ $limit: 5 }
261+
262+
During the optimization phase, the optimizer transforms the sequence to
263+
the following:
264+
265+
.. code-block:: javascript
266+
267+
{ $sort: { age : -1 } },
268+
{ $limit: 15 }
269+
{ $skip: 10 }
270+
271+
.. note::
272+
273+
The :agg:pipeline:`$limit` value has increased to the sum of the
274+
initial value and the :agg:pipeline:`$skip` value.
275+
276+
``$limit`` + ``$skip`` + ``$limit`` + ``$skip`` Sequence Optimization
277+
`````````````````````````````````````````````````````````````````````
278+
279+
When you have continuous sequence of :agg:pipeline:`$limit` pipeline
280+
stage followed by a :agg:pipeline:`$skip` pipeline stage, the
281+
aggregation will attempt to re-arrange the pipeline stages to combine
282+
the limits together and the skips together. For example, if the
283+
pipeline consists of the following stages:
284+
285+
.. code-block:: javascript
286+
287+
{ $limit: 100 },
288+
{ $skip: 5 },
289+
{ $limit: 10},
290+
{ $skip: 2 }
291+
292+
During the intermediate step, the optimizer reverses the position of
293+
the :agg:pipeline:`$skip` followed by a :agg:pipeline:`$limit` to
294+
:agg:pipeline:`$limit` followed by the :agg:pipeline:`$skip`.
295+
296+
.. code-block:: javascript
297+
298+
{ $limit: 100 },
299+
{ $limit: 15},
300+
{ $skip: 5 },
301+
{ $skip: 2 }
302+
303+
The :agg:pipeline:`$limit` value has increased to the sum of the
304+
initial value and the :agg:pipeline:`$skip` value. Then, for the final
305+
:agg:pipeline:`$limit` value, the optimizer selects the minimum between
306+
the adjacent :agg:pipeline:`$limit` values. For the final
307+
:agg:pipeline:`$skip` value, the optimizer adds the adjacent
308+
:agg:pipeline:`$skip` values, to transform the sequence to the
309+
following:
310+
311+
.. code-block:: javascript
312+
313+
{ $limit: 15 },
314+
{ $skip: 7 }
315+
239316
Memory for Cumulative Operators
240317
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
241318

@@ -247,6 +324,8 @@ implementation of :agg:pipeline:`$sort` does not go to disk in these
247324
cases: in order to sort the contents of the pipeline, the entire input
248325
must fit in memory.
249326

327+
.. include:: /includes/fact-agg-sort-limit.rst
328+
250329
:agg:pipeline:`$group` has similar characteristics: Before any
251330
:agg:pipeline:`$group` passes its output along the pipeline, it must
252331
receive the entirety of its input. For the :agg:pipeline:`$group`
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
.. versionchanged:: 2.4
2+
When a :agg:pipeline:`$sort` immediately precedes a
3+
:agg:pipeline:`$limit` in the pipeline, the :agg:pipeline:`$sort`
4+
operation only maintains the top n results as it progresses, where n
5+
is the specified limit. Before 2.4, :agg:pipeline:`$sort` would sort
6+
all the results in memory, and then limit the results to n results.

source/reference/aggregation/limit.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,6 @@ $limit (aggregation)
2424
by the pipeline. :pipeline:`$limit` has no effect on the content
2525
of the documents it passes.
2626

27+
.. note::
28+
29+
.. include:: /includes/fact-agg-sort-limit.rst

source/reference/aggregation/sort.txt

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -43,19 +43,20 @@ $sort (aggregation)
4343

4444
.. todo:: mention the importance of order preserving objects
4545

46-
- :agg:pipeline:`$skip`
46+
- :pipeline:`$skip`
4747

4848
:pipeline:`$sort` operator can take advantage of an index when
4949
placed at the **beginning** of the pipeline or placed **before**
5050
the following aggregation operators:
5151

52-
- :agg:pipeline:`$project`
53-
- :agg:pipeline:`$unwind`
54-
- :agg:pipeline:`$group`.
52+
- :pipeline:`$project`
53+
- :pipeline:`$unwind`
54+
- :pipeline:`$group`.
55+
56+
.. include:: /includes/fact-agg-sort-limit.rst
5557

5658
.. warning:: Unless the :pipeline:`$sort` operator can use an index,
57-
in the current release, the sort must fit within memory. This
58-
may cause problems when sorting large numbers of documents.
59+
the :pipeline:`$sort` operation must fit within memory.
5960

6061
.. todo:: if a sort precedes the first $group in a sharded system,
6162
all documents must go to the mongos for sorting.

source/release-notes/2.4.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -462,3 +462,8 @@ Improvements to the Aggregation Framework
462462
- :agg:group:`$min` operator only considers non-null and existing field
463463
values. If all the values for a field are ``null`` or are missing,
464464
the operator returns ``null`` for the minimum value.
465+
466+
- When a :agg:pipeline:`$sort` immediately precedes a
467+
:agg:pipeline:`$limit` in the pipeline, the :agg:pipeline:`$sort`
468+
operation only maintains the top n results as it progresses, where n
469+
is the specified limit.

0 commit comments

Comments
 (0)