@@ -236,6 +236,83 @@ affecting the result. However, at this time place
236
236
:agg:pipeline:`$match` operators at the beginning of the pipeline when
237
237
possible.
238
238
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
+
239
316
Memory for Cumulative Operators
240
317
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
241
318
@@ -247,6 +324,8 @@ implementation of :agg:pipeline:`$sort` does not go to disk in these
247
324
cases: in order to sort the contents of the pipeline, the entire input
248
325
must fit in memory.
249
326
327
+ .. include:: /includes/fact-agg-sort-limit.rst
328
+
250
329
:agg:pipeline:`$group` has similar characteristics: Before any
251
330
:agg:pipeline:`$group` passes its output along the pipeline, it must
252
331
receive the entirety of its input. For the :agg:pipeline:`$group`
0 commit comments