@@ -236,6 +236,83 @@ affecting the result. However, at this time place
236236:agg:pipeline:`$match` operators at the beginning of the pipeline when
237237possible.
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+
239316Memory for Cumulative Operators
240317~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
241318
@@ -247,6 +324,8 @@ implementation of :agg:pipeline:`$sort` does not go to disk in these
247324cases: in order to sort the contents of the pipeline, the entire input
248325must 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
252331receive the entirety of its input. For the :agg:pipeline:`$group`
0 commit comments