$setWindowFields Window Functions
Parent: mongodb-time-series · Published reference · snapshot 2026-09-19
↓ Facts as markdownall context files
Depth-first rabbithole dossier for $setWindowFields Window Functions; source-anchored research pack.
These notes link each claim to its source. A source may be a research report hosted on this site rather than the primary document. A published reference means the content is available; it does not certify independent review or accuracy.Read the editorial policy and follow the sources before relying on a claim.
Definitions
- - **"Collation is not supported in `$setWindowFields`" — not supported by primary sources.** This claim appears in aggregated web summaries. I actively looked for confirmation and found the opposite: SERVER-54693 "Add tests that $setWindowFields respects the collation" (created 2021-02-22, resolved 2021-03-22, fixVersion `4.9.0`) states "The relevant comparisons for window functions will be the partition key and the individual window function evaluation," and the manual's Restrictions section for the stage lists no collation restriction. Treat the "no collation" claim as unverified and probabl [source]
- **S3. Omitting `partitionBy` means one partition over the entire input**, and partitions compute independently of one another. `[M-A3] [P-2] [E-C2]` — https://www.mongodb.com/docs/manual/reference/operator/aggregation/setWindowFields/ [source]
Structure and components
- **D2. MongoDB's documented window-operator set has no direct equivalent for several standard SQL window functions.** The operator list published for `$setWindowFields` contains no `NTILE`, `PERCENT_RANK`, or `CUME_DIST` analogue, and window frames are limited to `documents` and `range` — there is no `GROUPS` frame mode and no frame-exclusion clause. *(Inference from the published operator and window-specification list, not an explicit MongoDB statement — flagged as lower-confidence.)* [source]
- **Concept:** `$setWindowFields` Window Functions **Parent context:** mongodb-time-series **Report type:** mechanism (parts, invariants, limits) **Date researched:** 2026-09-18 [source]
- 4. The same paper states the standards lineage directly: "Window functions, which are also known as analytic OLAP functions, are part of the SQL:2003 standard," and notes they "have been part of the SQL standard for more than a decade." <https://www.vldb.org/pvldb/vol8/p1058-leis.pdf> [source]
- **E4.** Range windows carry hard structural constraints: "Range windows require all `sortBy` values to be numbers. Time range windows require all `sortBy` values to be dates. Range and time range windows can only contain one `sortBy` field and the sort must be ascending." — https://www.mongodb.com/docs/manual/reference/operator/aggregation/setWindowFields/ [source]
- This report covers the operational use, trade-offs, evaluation signals, and concrete implications of the MongoDB aggregation stage `$setWindowFields` and its window operators. It stays inside that stage. Adjacent stages (`$densify`, `$fill`, `$group`) appear only where they are part of a documented `$setWindowFields` workflow. Time series *collections* are treated only as an execution substrate for this stage, not as a subject in their own right. Version statements reflect the MongoDB manual as published on 2026-09-18 (8.x line). [source]
- **S32. The paper is Leis, Kundhikanjana, Kemper & Neumann, PVLDB 8(10), 2015** (TU München), and it states the standards lineage directly: window functions "are part of the SQL:2003 standard" and "have been part of the SQL standard for more than a decade." `[H-3,4]` — https://www.vldb.org/pvldb/vol8/p1058-leis.pdf [source]
- **The disconfirming search was run and mostly came back empty — recorded as a finding, not a shortfall.** All four reports actively sought critical or contradicting treatments. What exists: the practice report's 403-gated performance post (C3), the community threads (S54, S63), and the sharding-reference omission (R1). What does not exist: any independent benchmark, any independent mechanism analysis, any peer-reviewed treatment of this stage, any third-party critique with measurements. Percona's post — the most likely independent critic — contains no performance comparison, no scalability ana [source]
- 27. Memory tracking was part of the original build-out, not a later addition: SERVER-54142 "Add memory usage tracking to $setWindowFields" was created 2021-01-29 (fixVersion `4.9.0`) and SERVER-55789 "Add explain metric for peak memory usage of $setWindowFields stage" carries fixVersion `5.0.0-rc0`. <https://jira.mongodb.org/browse/SERVER-54142> · <https://jira.mongodb.org/browse/SERVER-55789> [source]
- - **Missing SQL features (NTILE, frame exclusion, GROUPS frame mode).** Web summaries assert MongoDB lacks `NTILE` and SQL's `EXCLUDE CURRENT ROW` / `EXCLUDE TIES` frame-exclusion clauses. The absence is consistent with the manual's operator and window-option lists, which contain no such entries, but I found no official MongoDB statement acknowledging the gap. Recorded as an inference from absence, not as a sourced claim. <https://www.mongodb.com/docs/manual/reference/operator/aggregation/setWindowFields/> [source]
- 12. `range` and time-range frames "can only contain one `sortBy` field and the sort must be ascending". A compound or descending sort silently rules out range framing. — https://www.mongodb.com/docs/manual/reference/operator/aggregation/setWindowFields.md [source]
How it works
- **Concept:** `$setWindowFields` Window Functions **Parent context:** mongodb-time-series **Inputs:** four independent reports compiled 2026-09-18 — `mechanism.md`, `history.md`, `edge-cases.md`, `practice.md` **Synthesis date:** 2026-09-19 **Tree status:** not merged. This document does not edit `tree.json`. [source]
- This report covers only the MongoDB aggregation stage `$setWindowFields` and the window operators that run inside it: where the design came from, when it shipped, and how its surface has changed release by release. It does not cover sibling frontier concepts (time series collections themselves, `$densify`, `$fill`, bucketing/granularity) except where a source ties them directly to `$setWindowFields`. Every claim below carries an inline source URL. Claims are stated atomically; interpretation is labelled as such. [source]
- 9. The nested `window: { ... }` sub-document is not the original syntax. SERVER-54821 "Update $setWindowFields syntax to move window arguments under a new field" was created 2021-02-26 and resolved 2021-03-04, fixVersion `4.9.0` — i.e. the syntax was restructured during the pre-release cycle. <https://jira.mongodb.org/browse/SERVER-54821> [source]
- 3. When the `window` option is omitted the default frame is unbounded — it includes every document in the partition. Window boundaries, when given, are inclusive. — https://www.mongodb.com/docs/manual/reference/operator/aggregation/setWindowFields.md [source]
- **S4. Omitting `window` means an unbounded frame over the whole partition** — equivalent to `documents: ["unbounded", "unbounded"]`. Boundaries, when given, are inclusive. `[M-A4] [P-3] [H-15]` — https://www.mongodb.com/docs/manual/reference/operator/aggregation/setWindowFields/ [source]
- **S35. The nested `window: {...}` sub-document is not the original syntax.** SERVER-54821 "Update `$setWindowFields` syntax to move window arguments under a new field" was created 2021-02-26 and resolved 2021-03-04, fixVersion `4.9.0` — the shape was restructured during the pre-release cycle. `[H-9]` — https://jira.mongodb.org/browse/SERVER-54821 [source]
- 8. The stage was designed to desugar into surrounding stages where possible: SERVER-53397, created the same day, is "Desugar window function stage into preceding projection/sort when appropriate" (fixVersion `4.9.0`). <https://jira.mongodb.org/browse/SERVER-53397> [source]
- **B4.** A knob named `internalQueryAppendIdToSetWindowFieldsSort`, when enabled, appends `_id` to that generated sort pattern — a tie-break that makes the sort total and therefore makes window results deterministic across runs. — https://raw.githubusercontent.com/mongodb/mongo/master/src/mongo/db/pipeline/document_source_set_window_fields.cpp [source]
- **D1.** A window operator is a `WindowFunctionState` implementing `add()`, `remove()` and `getValue()`, and every implementation must preserve one invariant: "remove() undoes add() when called in FIFO order." The header states it as `add(x); add(y); remove(x)` being state-equivalent to `add(y)`, and `add(a); add(b); add(z); remove(a); remove(b)` equivalent to `add(z)`. — https://raw.githubusercontent.com/mongodb/mongo/master/src/mongo/db/pipeline/window_function/window_function.h [source]
- **F4.** On a sharded cluster the stage runs entirely on the merging half: `distributedPlanLogic()` returns `DistributedPlanLogic{nullptr, this, boost::none}` — a null shards-side stage and itself as the merging stage. Window computation is therefore not parallelised across shards, even when `partitionBy` matches the shard key. — https://raw.githubusercontent.com/mongodb/mongo/master/src/mongo/db/pipeline/document_source_set_window_fields.h [source]
- 28. The manual scopes block processing to "long running aggregation pipelines that begin with" `$match`, `$sort` (only when on the `timeField`), and `$group`. `$setWindowFields` is **not** in that list. — https://www.mongodb.com/docs/manual/core/timeseries/timeseries-querying.md [source]
- **S12. Desugaring was the design intent from the start, not a later optimisation.** SERVER-53397, created 2020-12-16 with fixVersion `4.9.0`, is titled "Desugar window function stage into preceding projection/sort when appropriate" — filed the same day as the skeleton stage ticket SERVER-53396. `[H-7,8]` — https://jira.mongodb.org/browse/SERVER-53396 · https://jira.mongodb.org/browse/SERVER-53397 [source]
- **S15. The generated sort is not total by default.** A server knob `internalQueryAppendIdToSetWindowFieldsSort`, when enabled, appends `_id` to the generated sort pattern as a tie-break, making the sort total and therefore making window results deterministic across runs. `[M-B4]` — https://raw.githubusercontent.com/mongodb/mongo/master/src/mongo/db/pipeline/document_source_set_window_fields.cpp [source]
- **S19. One unbounded output field pins the whole partition.** Expiry policies differ per output field — `kDefaultSequential` expires an index as soon as it is read, `kEndpoints`/`kRightEndpoint` defer to `releaseExpired()`, `kManual` hands control to the caller. Because release requires *all* slots to agree (S18), a single unbounded output field holds the entire partition in the buffer no matter how tight every other window in the same stage is. `[M-C3]` — https://raw.githubusercontent.com/mongodb/mongo/master/src/mongo/db/pipeline/window_function/partition_iterator.h [source]
- **S24. Every window operator is a `WindowFunctionState` with `add()`, `remove()`, `getValue()`, and must satisfy one invariant: "remove() undoes add() when called in FIFO order."** The header states it as `add(x); add(y); remove(x)` being state-equivalent to `add(y)`, and `add(a); add(b); add(z); remove(a); remove(b)` equivalent to `add(z)`. `[M-D1]` — https://raw.githubusercontent.com/mongodb/mongo/master/src/mongo/db/pipeline/window_function/window_function.h [source]
- **S28. On a sharded cluster the whole stage runs on the merging half.** `distributedPlanLogic()` returns `DistributedPlanLogic{nullptr, this, boost::none}` — a null shards-side stage and itself as the merging stage. Window computation is not parallelised across shards *even when `partitionBy` matches the shard key*. **This resolves a question two of the four reports left open — see §5, R1.** `[M-F4]` — https://raw.githubusercontent.com/mongodb/mongo/master/src/mongo/db/pipeline/document_source_set_window_fields.h [source]
- Three reports reached this and none resolved it. It is the single most consequential open question about this stage, because it determines whether a `$setWindowFields` pipeline scans. [source]
- **Position A — the manual says no (by omission).** The block-processing section scopes the feature to "long running aggregation pipelines that begin with" `$match`, `$sort` (only when on the `timeField`), and `$group`. **`$setWindowFields` is not in that list.** `[P-28]` — https://www.mongodb.com/docs/manual/core/timeseries/timeseries-querying.md [source]
Measurements and reference values
- 1. MongoDB engineers began explicit design work on window functions in early October 2020. Two Jira tasks titled "Research/Brainstorm and Propose Syntax for Window Functions" (SERVER-84999, SERVER-84989) and two titled "Brainstorm Design for Window Functions" (SERVER-84975, SERVER-85007) were all created 2020-10-02. <https://jira.mongodb.org/rest/api/2/search?jql=project%3DSERVER%20AND%20summary~%22window%20function%22%20ORDER%20BY%20created%20ASC> [source]
- **S30. Design work began 2020-10-02.** Four Jira tasks created that day — "Research/Brainstorm and Propose Syntax for Window Functions" (SERVER-84999, SERVER-84989) and "Brainstorm Design for Window Functions" (SERVER-84975, SERVER-85007). `[H-1]` — https://jira.mongodb.org/rest/api/2/search?jql=project%3DSERVER%20AND%20summary~%22window%20function%22%20ORDER%20BY%20created%20ASC [source]
- **F5.** The memory ceiling is 100 MB per stage. The manual's aggregation-pipeline-limits page names `$setWindowFields` explicitly among the stages that write temporary files to disk when `allowDiskUse` is `true`, alongside `$bucket`, `$bucketAuto`, `$group`, `$sort` and `$sortByCount`. — https://www.mongodb.com/docs/manual/core/aggregation-pipeline-limits/ [source]
- 17. `$setWindowFields` is on the official list of stages restricted to 100 MB of RAM that can write temporary files to disk when `allowDiskUse` is `true`, alongside `$group`, `$bucket`, `$bucketAuto`, `$sortByCount`, and unindexed `$sort`. — https://www.mongodb.com/docs/manual/core/aggregation-pipeline-limits.md [source]
- 29. MongoDB's own technical blog (published 2024-12-09, updated 2025-07-21) states the opposite emphasis: block processing "significantly improves performance, particularly for aggregation that leverage stages such as `$match`, `$sort`, `$group` and other analytical stages like `$setWindowFields`", and reports a 20x throughput improvement on an OHLC-plus-exponential- moving-average workload (6 million financial events over 7 days, Atlas M50 replica set), with a general range of 10–40x and outliers to 100x. — https://www.mongodb.com/company/blog/technical/key-enhancements-mongodb-8-0-block-proc [source]
Problems, failure modes and limitations
- - MongoDB Manual — `$setWindowFields` (aggregation stage): https://www.mongodb.com/docs/manual/reference/operator/aggregation/setWindowFields.md - MongoDB Manual — Aggregation Pipeline Limits: https://www.mongodb.com/docs/manual/core/aggregation-pipeline-limits.md - MongoDB Manual — About Querying Time Series Data (block processing): https://www.mongodb.com/docs/manual/core/timeseries/timeseries-querying.md - MongoDB Manual — Aggregation and Operator Considerations (time series): https://www.mongodb.com/docs/manual/core/timeseries/timeseries-aggregations-operators/ - MongoDB Manual — `$expMovi [source]
- **R2. "Is collation unsupported in `$setWindowFields`?" — RESOLVED: TRUE OF DOCUMENTDB, LIKELY FALSE OF MONGODB. The two reports were talking about different engines.** The history report found the claim in "aggregated web summaries," searched for confirmation, found the opposite, and concluded it is "unverified and probably wrong" `[H-disagreement-2]`: SERVER-54693 "Add tests that `$setWindowFields` respects the collation" (created 2021-02-22, resolved 2021-03-22, fixVersion `4.9.0`) states "The relevant comparisons for window functions will be the partition key and the individual window func [source]
- **Confidence handling, from the edge-cases report.** This is a vendor benchmark with no published methodology, no third-party replication, and no stated limitations or fallback conditions. **Treat the magnitude as unverified; the load-bearing claim is the direction — pre-8.0 time-series window queries were slow enough to be worth a dedicated execution-model rewrite.** `[E-C7]` [source]
- **A3. A single window specification cannot contain both `documents` and `range`.** The two frame types are mutually exclusive. This restriction is independently restated by the open-source DocumentDB MQL implementation: "Cannot use both documents and range in the same window specification." Sources: https://www.mongodb.com/docs/v8.0/reference/operator/aggregation/setwindowfields/ · https://documentdb.io/docs/reference/operators/aggregation/$setwindowfields/ [source]
- **A4. Rank operators (`$denseRank`, `$documentNumber`, `$rank`) and `$shift` use an implicit window and return an error if a `window` option is supplied.** For `$shift` the manual is explicit: "`$shift` returns an error if you specify a `window` in the `$setWindowFields` stage." Sources: https://www.mongodb.com/docs/v8.0/reference/operator/aggregation/setwindowfields/ · https://www.mongodb.com/docs/manual/reference/operator/aggregation/shift/ [source]
- **U5. Error-message quality was a known weak point.** MongoDB ticket SERVER-56849 ("Improve error reporting for `$setWindowFields`") records that the stage fails with "Unrecognized window function" without reporting the candidates it tried. The ticket's current status was not verified — it is cited as evidence that specification errors were historically hard to diagnose, not as a claim about present behaviour. [source]
- 28. The time series collection limitations page lists no restriction on `$setWindowFields` or window operators; the only aggregation-stage restriction named there is that `$merge` cannot write into a time series collection. <https://www.mongodb.com/docs/manual/core/timeseries/timeseries-limitations.md> [source]
- **E1.** Two window kinds exist and are mutually exclusive: "You cannot specify both a `documents` window and a `range` window." — https://www.mongodb.com/docs/manual/reference/operator/aggregation/setWindowFields/ [source]
- **E7.** Rank operators and `$shift` use an implicit window and "return an error if you specify a `window` option." Their window is fixed by the operator's definition and cannot be overridden. — https://www.mongodb.com/docs/manual/reference/operator/aggregation/setWindowFields/ [source]
- **F1.** `$setWindowFields` is declared `StreamType::kBlocking` and `DiskUseRequirement::kWritesTmpData`. It cannot emit a document until it has consumed enough input to close the relevant window. — https://raw.githubusercontent.com/mongodb/mongo/master/src/mongo/db/pipeline/document_source_set_window_fields.h [source]
- 4. Two frame kinds exist and are mutually exclusive: a `documents` frame addressed by integer offsets relative to the current document (`"unbounded"`, `"current"`, `±N`), and a `range` frame addressed by offsets applied to the `sortBy` value. "You cannot specify both a documents window and a range window." — https://www.mongodb.com/docs/manual/reference/operator/aggregation/setWindowFields.md [source]
- 9. Before MongoDB 5.3 the stage "cannot be used: within transactions [or] with `"snapshot"` read concern". From 5.3 onward both are permitted. This is the gate for reading a window result inside a transactional or point-in-time-consistent workflow. — https://www.mongodb.com/docs/manual/reference/operator/aggregation/setWindowFields.md [source]
- 10. `sortBy` is *required* for rank operators, order operators (`$first`, `$last`, `$shift`), any bounded window, and `$linearFill`. Omitting it in those cases is an error, not a silent default. — https://www.mongodb.com/docs/manual/reference/operator/aggregation/setWindowFields.md [source]
- 11. Rank operators and `$shift` use an implicit window and "return an error if you specify a `window` option". A frame cannot be narrowed for a ranking. — https://www.mongodb.com/docs/manual/reference/operator/aggregation/setWindowFields.md [source]
- 13. For time-range frames, "numeric boundary values must be integers. For example, you can use 2 hours as a boundary but you cannot use 1.5 hours." A 90-minute window must be expressed as 90 minutes, not 1.5 hours. — https://www.mongodb.com/docs/manual/reference/operator/aggregation/setWindowFields.md [source]
- 25. The same source reports that window functions run slower on time series collections than on regular collections, and that the covering-index remedy is unavailable there because such an index cannot be created on a time series collection; the suggested substitutes are larger bucket sizes and more sort memory. — https://medium.com/mongodb-performance-tuning/mongodb-windows-function-and-time-series-performance-8d742addac34 *(Same 403 caveat as claim 24. This is the report's main disconfirming source against the assumption that time series collections are the faster substrate for window functi [source]
- **S5. Two frame kinds, mutually exclusive.** A `documents` frame addresses by position (`"unbounded"`, `"current"`, integer offset where negative is before and positive is after); a `range` frame addresses by the *value* of the `sortBy` field. "You cannot specify both a `documents` window and a `range` window." `[M-E1,E2,E3] [P-4] [E-A3]` — https://www.mongodb.com/docs/manual/reference/operator/aggregation/setWindowFields/ · restated by an independent reimplementation ("Cannot use both documents and range in the same window specification") at https://documentdb.io/docs/reference/operators/aggr [source]
- **S40. Time series collections impose no documented restriction on the stage.** The time-series limitations page names only one aggregation-stage restriction — `$merge` cannot write into a time series collection — and says nothing about `$setWindowFields` or window operators. `[H-28]` — https://www.mongodb.com/docs/manual/core/timeseries/timeseries-limitations.md [source]
- **S42. Time-range windows: all `sortBy` values must be dates, and numeric boundaries must be integers.** "You can use 2 hours as a boundary but you cannot use 1.5 hours" — a 90-minute window must be written as 90 minutes. `[M-E5] [E-A2] [P-13]` — https://www.mongodb.com/docs/v8.0/reference/operator/aggregation/setwindowfields/ [source]
- **S43. `sortBy` is mandatory** for rank operators, order operators (`$first`, `$last`, `$shift`), any bounded window, and `$linearFill`. Omitting it is a specification error, not a silent fallback to collection order. `[M-E6] [E-A5] [P-10]` — https://www.mongodb.com/docs/manual/reference/operator/aggregation/setWindowFields/ [source]
- **S44. Rank operators and `$shift` reject a `window` option.** Their window is implicit and fixed by the operator definition. For `$shift` the manual is explicit: "`$shift` returns an error if you specify a `window` in the `$setWindowFields` stage." (Mechanism for *why*: see the inference under S26.) `[M-E7] [E-A4] [P-11]` — https://www.mongodb.com/docs/manual/reference/operator/aggregation/shift/ [source]
- **S47. Error-message quality was a known weak point.** SERVER-56849 "Improve error reporting for `$setWindowFields`" records the stage failing with "Unrecognized window function" without naming the candidates it tried. The ticket's current status was not verified in the source report; cite it as evidence that specification errors were historically hard to diagnose, not as a claim about present behaviour. `[E-U5]` — https://jira.mongodb.org/browse/SERVER-56849 [source]
- **S49. Empty or type-incompatible windows return a *value*, not an error.** `$count` and `$sum` return `0`; `$addToSet` and `$push` return `[]`; every other operator returns `null`. The manual's own incompatible-value example is "using `$sum` on strings" — which yields `0`, indistinguishable from a legitimately zero sum. Downstream code must distinguish "no data in window" from "the sum really is zero." `[M-E8] [E-B4] [P-15]` — https://www.mongodb.com/docs/manual/reference/operator/aggregation/setWindowFields/ [source]
- **Position B — an independent practitioner reports the opposite.** Window functions run *slower* on time series collections than on regular ones, and the covering-index remedy from C1/A′ is **unavailable there because such an index cannot be created on a time series collection**; the suggested substitutes are larger bucket sizes and more sort memory. `[P-25]` — https://medium.com/mongodb-performance-tuning/mongodb-windows-function-and-time-series-performance-8d742addac34 [source]
- **How to settle it:** block processing is automatic and cannot be requested; whether a query used it is visible only in the explain plan's slot-based plan stages `[P-27]` — https://www.mongodb.com/docs/manual/core/timeseries/timeseries-querying.md [source]
- **Two inferences I added and labelled as such**, neither stated by any source: one unbounded output field pins the whole partition buffer regardless of the other windows' tightness (follows from the slot-expiry protocol); and the non-total generated sort — `[partition key, sortBy]` with no `_id` tie-break unless `internalQueryAppendIdToSetWindowFieldsSort` is on — is a candidate root cause for the 2026-02-02 `$documentNumber` forum failure. The second is a hypothesis worth one experiment, not a finding. [source]
- **A5. `sortBy` is mandatory for the rank operators, the order operators (`$first`, `$last`, `$shift`), any bounded window, and `$linearFill`.** Omitting it is a specification error, not a silent fallback to collection order. [source]
- **A7. `$expMovingAvg` requires exactly one of `N` or `alpha`**: "You must specify either N or alpha. You cannot specify both." It is also stage-locked: "`$expMovingAvg` is only available in the `$setWindowFields` stage." [source]
- **B4. Empty or type-incompatible windows return a *value*, not an error.** For `$count` and `$sum` the returned value is `0`; for `$addToSet` and `$push` it is an empty array; for every other operator it is `null`. The manual gives "using `$sum` on strings" as the incompatible-value example — summing a string field yields `0`, which is indistinguishable from a legitimately zero sum. [source]
- **C1. `$setWindowFields` is one of the aggregation stages subject to the 100 MB per-stage memory limit and one of the stages that can spill to disk.** The documented spilling set is `$bucket`, `$bucketAuto`, `$group`, `$setWindowFields`, `$sort` (when not index-supported), and `$sortByCount`. [source]
- **C2. Spilling is not an unconditional escape hatch.** The limits page notes that some stages cannot output any documents until they have processed all incoming documents and must keep their output in RAM, "which may require more space than the 100 MB limit." A single very large partition is the practical boundary: partitioning is what bounds the working set, and a pipeline with `partitionBy` omitted defaults to one partition for the entire collection. Sources: https://www.mongodb.com/docs/manual/core/aggregation-pipeline-limits/ · https://www.mongodb.com/docs/v8.0/reference/operator/aggregati [source]
- **C3. The default failure mode depends on a server parameter, not on the pipeline.** From MongoDB 6.0, `allowDiskUseByDefault` controls whether a >100 MB stage spills (default true) or raises an error. The same `$setWindowFields` pipeline can throw on one deployment and succeed on another with identical data. [source]
- **C4. The diagnostics for C1–C3 are version-gated, which is itself a boundary condition.** `usedDisk` was introduced in MongoDB 5.3; `spills`, `spilledBytes`, `spilledRecords`, and `spilledDataStorageSize` in MongoDB 8.2; `peakTrackedMemBytes` in MongoDB 8.3. On a 5.0–5.2 server — the versions where `$setWindowFields` first shipped — none of these fields exist, so memory pressure in this stage cannot be measured from `explain` at all. [source]
- **C6. On sharded clusters, a blocking stage splits the pipeline into a parallel "Shards Part" and a single-location "Merger Part."** The aggregation engine splits at the first blocking stage; everything after runs in one place. **Caveat / gap:** this source names `$group`, `$bucket`, `$bucketAuto`, `$count`, `$sortByCount`, and `$sort` as the splitting stages and **does not mention `$setWindowFields` anywhere**. The inference that `$setWindowFields` forces a merge is therefore *not* directly sourced — see Unresolved Disagreement U2. [source]
- **U2. Whether `$setWindowFields` forces a shard-merge is not documented.** The stage is clearly blocking (it spills, it has a `peakTrackedMemBytes`, it cannot emit before consuming its partition). But the best available sharding reference enumerates blocking stages without including it, and the official `$setWindowFields` page says nothing about sharded execution. The behaviour is consistent with a merge but **unconfirmed by any source found**. Sources: https://www.practical-mongodb-aggregations.com/guides/sharding.html · https://www.mongodb.com/docs/manual/reference/operator/aggregation/setWi [source]
- 26. Memory behaviour is governed by the general aggregation limit: `$setWindowFields` is named as one of the stages that write temporary files to disk when they need more than 100 MB. From MongoDB 6.0 the `allowDiskUseByDefault` parameter defaults to true, so such spilling happens by default; when it is false the stage errors instead. <https://www.mongodb.com/docs/manual/core/aggregation-pipeline-limits.md> [source]
- **F3.** The transaction permission is version-gated. "Before MongoDB 5.3, the `$setWindowFields` stage cannot be used: within transactions [or] with `"snapshot"` read concern." Both are supported from 5.3. — https://www.mongodb.com/docs/manual/reference/operator/aggregation/setWindowFields/ [source]
- **F10.** Output documents remain bound by the 16 MiB BSON limit — "Each document in the result set is subject to the 16 mebibyte BSON Document Size limit" — but "the limit only applies to the returned documents. During the pipeline processing, the documents may exceed this size." An output field built by `$push` or `$addToSet` over a wide window is the realistic way to hit this. — https://www.mongodb.com/docs/manual/core/aggregation-pipeline-limits/ [source]
- **F11.** Validation errors surfaced by the desugaring include code `6307900`, `"$setWindowFields 'output' specification contains two conflicting paths"`, and a `TypeMismatch`: `"An expression used to partition cannot evaluate to value of type array"`. — https://raw.githubusercontent.com/mongodb/mongo/master/src/mongo/db/pipeline/document_source_set_window_fields.cpp [source]
- **U3 — Where the memory limit is documented.** The `$setWindowFields` reference page itself does not state the 100 MB limit, `allowDiskUse`, `$facet`/`$lookup` permission, or view restrictions; a targeted fetch of its restrictions anchor returned none of these (https://www.mongodb.com/docs/manual/reference/operator/aggregation/setWindowFields/). The limit lives only on the separate pipeline-limits page (F5). Anyone reading the operator page alone will not learn the stage can abort at 100 MB. [source]
- 7. Several operators exist *only* inside this stage and cannot be used elsewhere. The `$expMovingAvg` doc states "`$expMovingAvg` is only available in the `$setWindowFields` stage"; `$locf` and `$minMaxScaler` carry the same restriction. — https://www.mongodb.com/docs/manual/reference/operator/aggregation/expMovingAvg.md — https://www.mongodb.com/docs/manual/reference/operator/aggregation/locf.md — https://www.mongodb.com/docs/manual/reference/operator/aggregation/minmaxscaler.md [source]
- 20. The docs warn that stages which "can't output any documents until they have processed all incoming documents … may require more space than the 100 MB limit". `$setWindowFields` with an unbounded frame is exactly such a stage, so the 100 MB figure is a spill threshold, not a ceiling on actual consumption. — https://www.mongodb.com/docs/manual/core/aggregation-pipeline-limits.md [source]
- 22. Community-reported case (2023-05-14): a pipeline running `$setWindowFields` with `$denseRank` over roughly 4 million documents, followed by `$project` and then `$match`, was too slow for production. Indexes on the `$match` fields existed but could not be used, because the filter sits after a stage that must consume the entire partition. — https://www.mongodb.com/community/forums/t/setwindowfields-for-rank-aggregations-makes-filtering-extremely-slow/226353 [source]
- 23. The practical consequence of claim 22 is a pipeline-ordering rule: put every `$match` that can be pushed earlier *before* `$setWindowFields`, so indexes prune the input. A `$match` placed after the stage filters an already fully-computed result set. Note the semantic cost — ranks computed after filtering rank the filtered subset, not the whole collection — so this rewrite is only valid when the partition definition already excludes the filtered rows. — https://www.mongodb.com/community/forums/t/setwindowfields-for-rank-aggregations-makes-filtering-extremely-slow/226353 [source]
- **S9. 100 MB per-stage memory limit with spill-to-disk.** `$setWindowFields` is named on the manual's spilling-stage list beside `$bucket`, `$bucketAuto`, `$group`, unindexed `$sort` and `$sortByCount`. `[M-F5] [H-26] [E-C1] [P-17]` — https://www.mongodb.com/docs/manual/core/aggregation-pipeline-limits/ [source]
- > **Synthesis-level consequence (inference, not sourced).** S19 gives a mechanical explanation for > the documentation's warning `[P-20]` that stages which cannot emit before consuming all input > "may require more space than the 100 MB limit": the memory floor of a `$setWindowFields` stage is > set by its *widest* output field, not by the average of its output fields. No source states this; > it follows from S18 + S19 + the limits page. Flagged as inference. [source]
- > **Synthesis-level link (inference, not sourced).** S24–S26 explain a documented restriction the > manual states without reason: rank operators and `$shift` "return an error if you specify a > `window` option" (S31). Their value is defined relative to the current row via the optional-Value > path of S26, not accumulated over a frame, so there is no frame for a user-supplied `window` to > resize. The manual asserts the rule; the source shows why it exists. Flagged as inference — no > source connects the two. [source]
- **S27. The stage is declared blocking and disk-using**: `StreamType::kBlocking` and `DiskUseRequirement::kWritesTmpData`. It cannot emit a document until it has consumed enough input to close the relevant window. `[M-F1]` — https://raw.githubusercontent.com/mongodb/mongo/master/src/mongo/db/pipeline/document_source_set_window_fields.h [source]
- **S45. Per-operator constraints that bite in practice:** - `$rank` accepts only a single `sortBy` field `[E-A6]` — https://www.mongodb.com/docs/manual/reference/operator/aggregation/rank/ - `$expMovingAvg` requires exactly one of `N` or `alpha`: "You must specify either N or alpha. You cannot specify both." `[E-A7]` — https://www.mongodb.com/docs/manual/reference/operator/aggregation/expMovingAvg/ - `$integral` couples `unit` to `sortBy` type in *both* directions: a `unit` requires a date `sortBy`, and a non-date `sortBy` requires omitting `unit`. Its valid units are week/day/hour/minute/secon [source]
- **S46. Desugaring-level validation errors** include code `6307900`, `"$setWindowFields 'output' specification contains two conflicting paths"`, and a `TypeMismatch`: `"An expression used to partition cannot evaluate to value of type array"`. `[M-F11]` — https://raw.githubusercontent.com/mongodb/mongo/master/src/mongo/db/pipeline/document_source_set_window_fields.cpp [source]
- **S62. Output documents remain bound by the 16 MiB BSON limit.** "Each document in the result set is subject to the 16 mebibyte BSON Document Size limit," though "the limit only applies to the returned documents. During the pipeline processing, the documents may exceed this size." The realistic way to hit this is an output field built by `$push` or `$addToSet` over a wide window — i.e. the *same* construct that pins the partition buffer under S19. `[M-F10]` — https://www.mongodb.com/docs/manual/core/aggregation-pipeline-limits/ [source]
- **S63. An observed production failure from stage ordering.** A community-reported case dated 2023-05-14: a pipeline running `$setWindowFields` with `$denseRank` over roughly 4 million documents, then `$project`, then `$match`, was too slow for production. Indexes on the `$match` fields existed but could not be used, because the filter sits after a stage that must consume the entire partition. `[P-22]` — https://www.mongodb.com/community/forums/t/setwindowfields-for-rank-aggregations-makes-filtering-extremely-slow/226353 [source]
- **S64. The rule that follows, with its semantic caveat.** Push every `$match` that can move earlier *before* `$setWindowFields` so indexes prune the input; a `$match` after the stage filters an already fully-computed result set. **The rewrite is not always semantics-preserving**: ranks computed after filtering rank the filtered subset, not the whole collection, so it is valid only when the partition definition already excludes the filtered rows. `[P-23]` — https://www.mongodb.com/community/forums/t/setwindowfields-for-rank-aggregations-makes-filtering-extremely-slow/226353 [source]
- **R4. "Where is the memory limit documented?" — RESOLVED: NOT ON THE OPERATOR PAGE.** The `$setWindowFields` reference page does not state the 100 MB limit, `allowDiskUse`, `$facet`/`$lookup` permission, or view restrictions; a targeted fetch of its restrictions anchor returned none of these. The limit lives only on the separate pipeline-limits page. **Anyone reading the operator page alone will not learn the stage can abort at 100 MB** — a documentation defect worth recording as a finding about the concept's public record, not about the stage. `[M-U3]` — https://www.mongodb.com/docs/manual/re [source]
- 1. `$setWindowFields`, current manual — https://www.mongodb.com/docs/manual/reference/operator/aggregation/setWindowFields/ (also cited as https://www.mongodb.com/docs/manual/reference/operator/aggregation/setWindowFields.md) 2. `$setWindowFields`, v8.0 manual — https://www.mongodb.com/docs/v8.0/reference/operator/aggregation/setwindowfields/ 3. `$setWindowFields`, archived v5.0 manual — https://www.mongodb.com/docs/v5.0/reference/operator/aggregation/setWindowFields.md 4. MongoDB 5.0 release notes — https://www.mongodb.com/docs/v5.0/release-notes/5.0.md 5. MongoDB 8.0 changelog (SERVER-99887) [source]
Comparisons and alternatives
- **U4. Independent critical coverage of `$setWindowFields` is thin.** Percona's window-functions post (dated 2022-06-29) is the most prominent non-vendor treatment found; it acknowledges that "There are a few restrictions about window functions usage. Please have a look at the official documentation in case you hit some of them" but enumerates none, offers no benchmarks, and makes no SQL feature-parity comparison. Its efficiency claim ("a single query" versus "multiple queries...and saving somewhere temporary data") is unsubstantiated by measurement. Treat it as weak corroboration only. [source]
- **S67. Measured against PostgreSQL's window functions, MongoDB has no equivalent of `ntile()`, `percent_rank()`, `cume_dist()` or `nth_value()`, and offers only `documents`/`range` framing — no `GROUPS` frame mode and no frame-exclusion clause (`EXCLUDE CURRENT ROW` / `EXCLUDE TIES`).** `$shift` covers `lag()`/`lead()`; `$rank`, `$denseRank`, `$documentNumber` cover `rank()`, `dense_rank()`, `row_number()`. **All three reports that raise this flag it as inference from the absence of entries in MongoDB's published operator list, not as an MongoDB statement** — the practice report is the stronge [source]
- **Reconciliation offered, unsourced.** The practice report proposes that the benefit is *indirect* — block processing accelerates the `$match`/`$sort`/`$group` prefix feeding the window stage rather than the window computation itself. Neither source states this. `[P-disagreement-1]` [source]
- **C7. MongoDB's own 8.0 materials imply `$setWindowFields` on time-series collections was a significant bottleneck before block processing.** The block-processing announcement (dated 2024-12-09, updated 2025-07-21) attributes time-series inefficiency to "the need to unpack and reshape a large volume of compressed data," names `$setWindowFields` among the stages that benefit, and claims "10-40x, with some large-scale aggregations reaching up to 100x." Its one concrete benchmark is an OHLC-plus-exponential-moving-average query over ~6 million events (10 symbols, 1/second, 7 days) on an Atlas M50 [source]
- 1. https://www.mongodb.com/docs/manual/reference/operator/aggregation/setWindowFields/ — `$setWindowFields`, current manual 2. https://www.mongodb.com/docs/v8.0/reference/operator/aggregation/setwindowfields/ — `$setWindowFields`, v8.0 manual 3. https://www.mongodb.com/docs/manual/core/aggregation-pipeline-limits/ — aggregation pipeline limits, spilling stages, `allowDiskUseByDefault` 4. https://www.mongodb.com/docs/manual/reference/explain-results/ — `usedDisk`, `spills`, `peakTrackedMemBytes` and their introducing versions 5. https://www.mongodb.com/docs/manual/reference/operator/aggregation [source]
- **D3.** `getValue()` takes an optional current-document `Value`: "some window functions implementations do not need the input Value of the current document and expect to be able to be called without it. Other window functions require this input Value and can assert this value present." This is how operators like `$rank` and `$shift`, which are defined relative to the current row rather than over an aggregate, share the same interface. — https://raw.githubusercontent.com/mongodb/mongo/master/src/mongo/db/pipeline/window_function/window_function.h [source]
- **E5.** Time range windows (`unit` set to one of year/quarter/month/week/day/ hour/minute/second/millisecond) require integer boundary values: "you can use 2 hours as a boundary but you cannot use 1.5 hours." Non-date, null and missing values are excluded from the window rather than coerced. — https://www.mongodb.com/docs/manual/reference/operator/aggregation/setWindowFields/ [source]
- **E8.** Empty or type-incompatible windows return a defined value rather than an error: `$count` and `$sum` return `0`, `$addToSet` and `$push` return `[]`, all other operators return `null`. — https://www.mongodb.com/docs/manual/reference/operator/aggregation/setWindowFields/ [source]
- **U4 — Disconfirming search returned little.** I actively searched for critical or contradicting treatments (performance complaints, index-usage failures, JIRA tickets on spilling). The Percona post — the most likely independent critic — contains no performance comparison, scalability analysis or SQL-equivalence discussion at all, and defers on restrictions: it "mentions 'restrictions about window functions usage' exist but defers readers to official documentation" (https://www.percona.com/blog/window-functions-in-mongodb-5-0/). Studio 3T likewise offers no SQL comparison (https://studio3t.com [source]
- 1. `$setWindowFields` was introduced in MongoDB 5.0 and performs operations on a span of documents called a *window*, appending the result as a new field to each document rather than collapsing documents the way `$group` does. — https://www.mongodb.com/docs/manual/reference/operator/aggregation/setWindowFields.md [source]
- 14. `range` frames exclude missing, undefined, and `null` `sortBy` values; time-range frames include "only date and time types". Rows with a null sort key therefore drop out of every window silently rather than raising an error. — https://www.mongodb.com/docs/manual/reference/operator/aggregation/setWindowFields.md [source]
- 15. Empty or type-incompatible windows return operator-dependent values rather than erroring: `0` for `$count` and `$sum`, `[]` for `$addToSet` and `$push`, and `null` for every other operator. Downstream code must distinguish "no data in window" from "sum is genuinely zero". — https://www.mongodb.com/docs/manual/reference/operator/aggregation/setWindowFields.md [source]
- 1. **Does block processing accelerate `$setWindowFields`?** The MongoDB manual's block-processing section names only `$match`, `$sort` on the `timeField`, and `$group` (https://www.mongodb.com/docs/manual/core/timeseries/timeseries-querying.md), while MongoDB's own technical blog names `$setWindowFields` as a beneficiary and headlines a 20x result on a workload whose analytic step is an exponential moving average (https://www.mongodb.com/company/blog/technical/key-enhancements-mongodb-8-0-block-processing). A plausible reconciliation is that the benefit is indirect — block processing accelerat [source]
- **S48. Range windows shrink silently around bad data.** "For range windows, only numbers in the specified range are included in the window. Missing, undefined, and `null` values are excluded." Time-range windows include only date and time types; numeric, missing, undefined and `null` values are excluded. A partition with sparse or mistyped sort values yields averages and sums over fewer documents than the author expects, with no diagnostic. Mechanically this is S20: `getEndpoints()` clamps and filters rather than raising. `[E-B3] [P-14] [M-E5,C6]` — https://www.mongodb.com/docs/manual/referenc [source]
- - **R1 — sharding: resolved.** Two reports left "does `$setWindowFields` force a shard-merge?" open because the standard sharding reference omits the stage from its blocking-stage list. The mechanism report's source read answers it: `distributedPlanLogic()` returns `{nullptr, this, boost::none}` — the whole stage runs on the merging half, and `partitionBy` matching the shard key does **not** parallelise it. Widely-read third-party guidance under-describes this cost. - **R2 — collation: resolved as an engine confusion.** The history report chased "collation is not supported in `$setWindowFields [source]
- **B3. Range windows silently *shrink* around bad data rather than erroring.** "For range windows, only numbers in the specified range are included in the window. Missing, undefined, and `null` values are excluded." For time-range windows, only date and time types are included; numeric, missing, undefined, and `null` values are excluded. A partition with sparse or mistyped sort values therefore produces averages and sums over fewer documents than the author expects, with no diagnostic. [source]
- - **Stable API V1 status: docs vs. ticket.** The Stable API changelog states `$setWindowFields` was added to Stable API V1 in MongoDB 6.0, and the current server source registers the stage with `AllowedWithApiStrict::kAlways`. But SERVER-56161 "Add $setWindowFields to API Version 1" is still listed as **Unresolved** with no fixVersion. The documentation and the source agree; the open ticket appears to be stale bookkeeping, but I could not find a resolved ticket that records the 6.0 inclusion. <https://www.mongodb.com/docs/manual/reference/stable-api-changelog.md> · <https://jira.mongodb.org/re [source]
- **A2.** The stage appends fields to existing documents rather than collapsing them: "The `$setWindowFields` stage appends new fields to existing documents. You can include one or more `$setWindowFields` stages in an aggregation operation." This is the structural difference from `$group`, which reduces the document set. — https://www.mongodb.com/docs/manual/reference/operator/aggregation/setWindowFields/ — corroborated: https://studio3t.com/whats-new/what-is-setwindowfields-and-why-is-it-so-neat/ [source]
- **C6.** `getEndpoints()` converts a declared `WindowBounds` into a concrete `[lower, upper]` index pair against the buffer, clamping at partition edges — at the start of a partition, `DocumentBased{-10, +7}` resolves to `[0, +7]`. Range bounds are resolved against `_sortExpr`, the expression identifying the sort/time field. This is the invariant behind A4 and behind the fact that windows silently shrink at partition edges instead of erroring. — https://raw.githubusercontent.com/mongodb/mongo/master/src/mongo/db/pipeline/window_function/partition_iterator.h [source]
- **D2.** That FIFO add/remove contract is what makes a sliding window incremental: as the window advances by one document the engine removes the departing document and adds the arriving one, instead of recomputing the aggregate over the whole window. Cost per document is therefore O(1) amortised for removable operators rather than O(window size). — https://raw.githubusercontent.com/mongodb/mongo/master/src/mongo/db/pipeline/window_function/window_function.h [source]
- **U2 — Is `$setWindowFields` a recognised pipeline-splitting stage?** *Practical MongoDB Aggregations* enumerates the stages that split a pipeline in a sharded cluster as `$sort`, `$group`, `$bucket`, `$bucketAuto`, `$count` and `$sortByCount`, and does not name `$setWindowFields` at all (https://www.practical-mongodb-aggregations.com/guides/sharding.html). The server source contradicts the omission: `distributedPlanLogic()` forces the entire stage onto the merging half (F4). This is most likely an omission of a post-publication stage rather than a substantive disagreement, but it is worth rec [source]
- 30. Gap filling in a time series is expressed with `$locf` (last observation carried forward) or `$linearFill` inside `$setWindowFields`. Using the operator form rather than the `$fill` stage lets the filled value land in a *different* field than the source, so several fill methods can run side by side in one stage. — https://www.mongodb.com/docs/manual/reference/operator/aggregation/locf.md [source]
- 3. **Per-partition versus per-stage memory accounting.** The documented limit is 100 MB for the stage (https://www.mongodb.com/docs/manual/core/aggregation-pipeline-limits.md). No source consulted states whether the accounting is per partition or across the whole stage, nor names a `$setWindowFields`-specific server parameter analogous to `internalQueryMaxAllowedDensifyDocs`. Searches for `internalDocumentSourceSetWindowFieldsMaxMemoryBytes` returned no authoritative page. Unresolved; the 8.3 `peakTrackedMemBytes` explain field is the way to measure it empirically rather than reason about it. [source]
- **S20. Bounds are resolved against the buffer and clamped at partition edges.** `getEndpoints()` converts a declared `WindowBounds` into a concrete `[lower, upper]` index pair; at the start of a partition `DocumentBased{-10, +7}` resolves to `[0, +7]`. Range bounds resolve against `_sortExpr`, the expression identifying the sort/time field. Windows therefore *shrink silently* at partition edges instead of erroring — the invariant behind S4 and behind the edge-behaviour cluster in §4.2. `[M-C6]` — https://raw.githubusercontent.com/mongodb/mongo/master/src/mongo/db/pipeline/window_function/parti [source]
- **S25. That invariant is what makes a sliding window incremental.** As the window advances one document the engine removes the departing document and adds the arriving one rather than recomputing over the whole frame — O(1) amortised per document for removable operators rather than O(window size). `[M-D2]` — https://raw.githubusercontent.com/mongodb/mongo/master/src/mongo/db/pipeline/window_function/window_function.h [source]
- **R1. "Does `$setWindowFields` force a shard-merge?" — RESOLVED YES.** The edge-cases report marked this **unconfirmed by any source found** `[E-U2]`, reasoning only that the stage is clearly blocking. It had found that the best available sharding reference enumerates the splitting stages — `$sort`, `$group`, `$bucket`, `$bucketAuto`, `$count`, `$sortByCount` — and **omits `$setWindowFields` entirely** `[E-C6]`, a gap the mechanism report independently hit `[M-U2]`. The mechanism report resolves it from primary source: `distributedPlanLogic()` returns `DistributedPlanLogic{nullptr, this, boost [source]
- **R3. "Is there a `$setWindowFields`-specific memory parameter?" — PARTIALLY RESOLVED.** The practice report searched for `internalDocumentSourceSetWindowFieldsMaxMemoryBytes` and "returned no authoritative page," leaving the per-partition-versus-per-stage question open `[P-disagreement-3]`. The mechanism report found the parameter named with its default — `104857600` (100 MiB) — in captured `explain` `serverParameters` output on MongoDB 6.0.6 (S55) `[M-F6]`. **Resolved:** the parameter exists and is named; the 100 MB figure is not merely the generic pipeline limit applied by analogy. **Still [source]
- **Position B — MongoDB's own blog says yes, loudly.** Block processing "significantly improves performance, particularly for aggregation that leverage stages such as `$match`, `$sort`, `$group` and other analytical stages like `$setWindowFields`," with "10-40x, with some large-scale aggregations reaching up to 100x," and one concrete benchmark: an OHLC-plus-exponential-moving- average query over ~6 million events (10 symbols, 1/second, 7 days) on an Atlas M50 replica set saw "operations per second improve by an incredible 2000%, or 20x" versus 7.0. Published 2024-12-09, updated 2025-07-21. `[P [source]
- **What would move the needle, in priority order.** 1. One `explain()` on a `$setWindowFields` pipeline with a compound `(partitionBy, sortBy)` index present and absent, on a regular collection — settles C1, the highest-value open question. 2. One `explain()` with and without `internalQueryAppendIdToSetWindowFieldsSort` on data with duplicate `(partition, sortBy)` pairs — tests the R5 hypothesis for the S54 failure. 3. One `explain()` reading slot-based plan stages on a time-series `$setWindowFields` pipeline on 8.x — settles C2's direct-versus-indirect question. 4. Pin the §2 source reads to a [source]
Facts and statements
- **Position A — MongoDB positions them as the natural substrate.** The manual lists `$setWindowFields` among the "Frequently Used Operations" for analyzing time series data `[P-26]`; the 5.0 release notes pitch it for time series analysis `[H-13]`; the time-series limitations page imposes no restriction on it `[H-28]`. — https://www.mongodb.com/docs/manual/core/timeseries/timeseries-aggregations-operators/ · https://www.mongodb.com/docs/v5.0/release-notes/5.0.md · https://www.mongodb.com/docs/manual/core/timeseries/timeseries-limitations.md [source]
- **Concept:** `$setWindowFields` Window Functions **Parent context:** mongodb-time-series **Report type:** edge cases / boundary conditions / disconfirming evidence **Date compiled:** 2026-09-18 [source]
- **U1. Whether Amazon DocumentDB supports `$setWindowFields` is contradicted across sources.** Some compatibility matrices list `$setWindowFields` (MongoDB 5.0+ window functions) as unsupported on Amazon DocumentDB, while MongoDB's own DocumentDB compatibility page for drivers presents it as supported. Support plausibly varies by cluster version. Not resolved here; the AWS release notes for a specific cluster version are the authority and were not consulted. Sources: https://www.mongodb.com/docs/drivers/documentdb-support/ · https://documentdb.io/docs/reference/operators/aggregation/$setwindowf [source]
- 17. At launch the feature was deliberately kept out of Stable API V1. SERVER-56160 "Exclude $setWindowFields from API Version 1" (created 2021-04-19, resolved 2021-04-20, fixVersion `5.0.0-rc0`) gives the reason: "The window functions are considered somewhat unstable while we validate with the beta program whether some of our design and semantic choices were reasonable." <https://jira.mongodb.org/browse/SERVER-56160> [source]
- 1. MongoDB Manual — `$setWindowFields` (aggregation stage) https://www.mongodb.com/docs/manual/reference/operator/aggregation/setWindowFields/ 2. MongoDB Manual — Aggregation Pipeline Limits https://www.mongodb.com/docs/manual/core/aggregation-pipeline-limits/ 3. MongoDB Manual — 8.0 Changelog (SERVER-99887) https://www.mongodb.com/docs/manual/release-notes/8.0-changelog/ 4. MongoDB Manual — Release Notes for MongoDB 8.3 (`peakTrackedMemBytes`) https://www.mongodb.com/docs/manual/release-notes/8.3/ 5. mongodb/mongo source — `document_source_set_window_fields.h` https://raw.githubusercontent.co [source]
- 34. Measured against SQL window functions as implemented in PostgreSQL, MongoDB's operator list has no equivalent of `ntile()`, `percent_rank()`, `cume_dist()`, or `nth_value()`, and offers only `documents`/`range` framing — there is no `GROUPS` frame mode and no frame-exclusion clause. `$shift` covers `lag()`/`lead()`; `$rank`, `$denseRank`, and `$documentNumber` cover `rank()`, `dense_rank()`, and `row_number()`. — https://www.postgresql.org/docs/current/functions-window.html — https://www.mongodb.com/docs/manual/reference/operator/aggregation/setWindowFields.md [source]
- 2. **Are time series collections faster or slower for window functions?** MongoDB positions `$setWindowFields` as a frequently used time series operation (https://www.mongodb.com/docs/manual/core/timeseries/timeseries-aggregations-operators/), while the independent performance-tuning source reports window functions running slower on time series collections than on regular ones and the covering-index remedy being unavailable there (https://medium.com/mongodb-performance-tuning/mongodb-windows-function-and-time-series-performance-8d742addac34). That source is undated in the material obtained and [source]
- Compatibility matrices disagree: some list `$setWindowFields` (MongoDB 5.0+ window functions) as **unsupported** on Amazon DocumentDB, while MongoDB's own DocumentDB compatibility page for drivers presents it as **supported**. Support plausibly varies by cluster version. **The AWS release notes for a specific cluster version are the authority and were not consulted by any of the four reports.** Note this is a different artifact from the open-source DocumentDB MQL implementation in S66/R2 — do not collapse them. `[E-U1]` — https://www.mongodb.com/docs/drivers/documentdb-support/ · https://docum [source]
- 46. PostgreSQL documentation — Window Functions (SQL parity baseline) — https://www.postgresql.org/docs/current/functions-window.html 47. DocumentDB MQL reference — `$setWindowFields` (open-source reimplementation; source of the collation and `$median`/`$percentile` limitations) — https://documentdb.io/docs/reference/operators/aggregation/$setwindowfields/ [source]
- 48. Percona — Corrado Pandiani, "Window Functions in MongoDB 5.0", 2022-06-29 — https://www.percona.com/blog/window-functions-in-mongodb-5-0/ 49. Studio 3T — "What is `$setWindowFields` and why is it so neat?" — https://studio3t.com/whats-new/what-is-setwindowfields-and-why-is-it-so-neat/ 50. LearnMongo — "Query Plans: The Basics" (explain `serverParameters` capture on 6.0.6; sole source for `internalDocumentSourceSetWindowFieldsMaxMemoryBytes`) — https://learnmongo.com/query-plans-the-basics/ 51. Practical MongoDB Aggregations Book — Sharding Considerations (omits the stage from its blocking- [source]
- **Handling.** Position B is the practice report's designated disconfirming source and the only material in this run that contradicts the marketing framing. It is also the weakest-sourced claim in the run: HTTP 403 on direct fetch, content from a search index, **undated in the material obtained, and predating the 8.0 block-processing work** — so C2 may have overtaken it. Unresolved in both directions: nobody has shown B is still true, and nobody has shown A was ever measured. [source]
- This report covers only the MongoDB aggregation stage `$setWindowFields` and the window operators that run inside it (`$rank`, `$denseRank`, `$documentNumber`, `$shift`, `$expMovingAvg`, `$integral`, `$derivative`, `$linearFill`, `$locf`, and the accumulator operators used in a window). It deliberately does not cover sibling time-series topics such as `$densify`, bucketing internals, time-series collection design, or the general aggregation framework, except where those touch a `$setWindowFields` boundary condition directly. [source]
- **B1. `$setWindowFields` does not guarantee the order of the documents it emits.** The manual states flatly: "The `$setWindowFields` stage doesn't guarantee the order of the returned documents." `sortBy` establishes order *for the window computation only*; a downstream `$sort` is required to make output order deterministic. [source]
- **D1. The open-source DocumentDB MQL implementation supports most window operators but not all.** It documents `$median` and `$percentile` as "not yet supported," and states "Collation is not supported in `$setWindowFields`." A pipeline that ranks or partitions on strings under a non- default collation is therefore not portable to that engine. [source]
- 2. The design was grounded in the academic literature on SQL window functions. Six Jira tasks created 2020-10-15 are titled `Read "Efficient Processing of Window Functions in Analytical SQL Queries"` (SERVER-84959, SERVER-84971, SERVER-85036, SERVER-85049, SERVER-85073, SERVER-85087). SERVER-84959 was resolved 2020-10-22 and its description links to `vldb.org/pvldb/vol8/p1058-leis.pdf`. <https://jira.mongodb.org/browse/SERVER-84959> [source]
- 3. That paper is *Efficient Processing of Window Functions in Analytical SQL Queries* by Viktor Leis, Kan Kundhikanjana, Alfons Kemper and Thomas Neumann (Technische Universität München), *Proceedings of the VLDB Endowment*, Vol. 8, No. 10, 2015. <https://www.vldb.org/pvldb/vol8/p1058-leis.pdf> [source]
- 6. Implementation was gated behind a feature flag. SERVER-52025 "Create feature flag for Window Functions" was created 2020-10-30 and resolved 2021-01-11; SERVER-52328 "Enable feature flag for Window Functions" carries fixVersion `5.0.0-rc0`. <https://jira.mongodb.org/browse/SERVER-52025> · <https://jira.mongodb.org/browse/SERVER-52328> [source]
- 15. Two frame modes shipped at 5.0: a `documents` window with boundaries relative to document position, and a `range` window with boundaries relative to the `sortBy` value, plus a `unit` option (`year` … `millisecond`) that turns a `range` window into a time range window. Boundaries are inclusive; the default is an unbounded window over the partition. <https://www.mongodb.com/docs/v5.0/reference/operator/aggregation/setWindowFields.md> [source]
- 21. `$setWindowFields` was added to Stable API V1 in MongoDB 6.0, as were its 5.0-era window operators (`$rank`, `$denseRank`, `$documentNumber`, `$shift`, `$derivative`, `$integral`, `$expMovingAvg`, `$covariancePop`, `$covarianceSamp`, `$locf`, and others). <https://www.mongodb.com/docs/manual/reference/stable-api-changelog.md> [source]
- 22. `$percentile` and `$median` are "New in version 7.0" and are usable as window operators; the manual notes that in a `$setWindowFields` stage the `input` must be a field name, not an array, and that `$percentile` uses the t-digest algorithm for approximate results. <https://www.mongodb.com/docs/manual/reference/operator/aggregation/percentile.md> [source]
- - $setWindowFields, current manual — <https://www.mongodb.com/docs/manual/reference/operator/aggregation/setWindowFields/> - $setWindowFields, archived 5.0 manual — <https://www.mongodb.com/docs/v5.0/reference/operator/aggregation/setWindowFields.md> - MongoDB 5.0 release notes (release date, Window Operators section) — <https://www.mongodb.com/docs/v5.0/release-notes/5.0.md> - $locf — <https://www.mongodb.com/docs/manual/reference/operator/aggregation/locf.md> - $linearFill — <https://www.mongodb.com/docs/manual/reference/operator/aggregation/linearFill.md> - $percentile — <https://www.mongod [source]
- - SERVER-84959 — read the Leis et al. VLDB paper — <https://jira.mongodb.org/browse/SERVER-84959> - SERVER-52025 / SERVER-52328 — window functions feature flag — <https://jira.mongodb.org/browse/SERVER-52025> - SERVER-53396 / SERVER-53397 — skeleton stage and desugaring — <https://jira.mongodb.org/browse/SERVER-53396> - SERVER-54142 / SERVER-55789 — memory tracking and explain metric — <https://jira.mongodb.org/browse/SERVER-54142> - SERVER-54693 — collation tests — <https://jira.mongodb.org/browse/SERVER-54693> - SERVER-54821 — syntax restructuring — <https://jira.mongodb.org/browse/SERVER-54 [source]
- - Leis, Kundhikanjana, Kemper, Neumann, "Efficient Processing of Window Functions in Analytical SQL Queries", PVLDB 8(10), 2015 — <https://www.vldb.org/pvldb/vol8/p1058-leis.pdf> - Eisenberg et al., "SQL:2003 Has Been Published", ACM SIGMOD Record, March 2004 — <https://dl.acm.org/doi/pdf/10.1145/974121.974142> - SQL:2003 overview (window functions, SQL:1999 OLAP amendment) — <https://en.wikipedia.org/wiki/SQL:2003> - Corrado Pandiani, "Window Functions in MongoDB 5.0", Percona, 2022-06-29 — <https://www.percona.com/blog/window-functions-in-mongodb-5-0/> [source]
- This report covers only the `$setWindowFields` aggregation stage itself: what it expands into, how it holds and walks documents, how window bounds are resolved, what state a window operator keeps, and where the stage stops working. It does not cover sibling time-series concepts (`$densify`, `$fill`, bucketing, time-series collections), the individual window operators as standalone topics, or SQL window-function theory except where a claim about `$setWindowFields` depends on the comparison. [source]
- **A1.** `$setWindowFields` takes three top-level fields: optional `partitionBy` (an expression), `sortBy` (a document of field/direction pairs), and required `output` (a document mapping new field names to window operators). — https://www.mongodb.com/docs/manual/reference/operator/aggregation/setWindowFields/ [source]
- **A4.** With the per-output `window` sub-document omitted, the default window is unbounded over the whole partition — equivalent to `documents: ["unbounded", "unbounded"]`. — https://www.mongodb.com/docs/manual/reference/operator/aggregation/setWindowFields/ [source]
- **A6.** The stage does not guarantee output order: "The `$setWindowFields` stage doesn't guarantee the order of the returned documents." A `sortBy` orders the window computation, not the result set; callers needing ordered output must add their own `$sort` after the stage. — https://www.mongodb.com/docs/manual/reference/operator/aggregation/setWindowFields/ [source]
- **E2.** A `documents` window addresses by position. Boundaries are `"current"`, `"unbounded"`, or an integer offset (negative = before, `0` = current, positive = after). — https://www.mongodb.com/docs/manual/reference/operator/aggregation/setWindowFields/ [source]
- **E3.** A `range` window addresses by the *value* of the `sortBy` field; a numeric boundary is added to the current document's sort value and documents whose sort value falls inclusively inside the result are included. — https://www.mongodb.com/docs/manual/reference/operator/aggregation/setWindowFields/ [source]
- **E6.** `sortBy` is mandatory for three cases — rank and order window operators, any bounded window (`documents` or `range`), and `$linearFill`. — https://www.mongodb.com/docs/manual/reference/operator/aggregation/setWindowFields/ [source]
- 2. The stage takes three operands: `partitionBy` (optional expression; default is a single partition covering the whole collection), `sortBy` (same syntax as `$sort`; default is no sorting), and `output` (required; maps new field names to window operators). — https://www.mongodb.com/docs/manual/reference/operator/aggregation/setWindowFields.md [source]
- 16. "The `$setWindowFields` stage doesn't guarantee the order of the returned documents." A `$sort` after the stage is required if the client depends on order, even though the stage sorted internally to compute the windows. — https://www.mongodb.com/docs/manual/reference/operator/aggregation/setWindowFields.md [source]
- 26. The MongoDB manual lists `$setWindowFields` among the "Frequently Used Operations" for analyzing time series data, describing it as running "calculations on documents in a given window". — https://www.mongodb.com/docs/manual/core/timeseries/timeseries-aggregations-operators/ [source]
- 33. DocumentDB, an independent open-source MQL reimplementation, supports most window operators but explicitly does not implement `$median` or `$percentile` as window operators, and states "Collation is not supported in `$setWindowFields`". Pipelines that rank or bucket text with a non-default collation are not portable across MQL implementations. — https://documentdb.io/docs/reference/operators/aggregation/$setwindowfields/ [source]
- Depth-first on this stage only. Covered: what `$setWindowFields` expands into, how it holds and walks documents, how bounds resolve, what state a window operator keeps, where it errors, where it silently lies, how the surface changed release by release, and where the four reports disagree with each other or with their own sources. [source]
- Not covered: `$densify`, `$fill`, bucketing, time-series collection design, or the individual window operators as standalone topics — they appear only where a `$setWindowFields` boundary condition runs through them. [source]
- **S1. The stage appends, it does not collapse.** `$setWindowFields` computes over a span of documents called a window and writes the result as a new field on each input document. This is the structural difference from `$group`, which reduces the document set. `[M-A2] [P-1]` — https://www.mongodb.com/docs/manual/reference/operator/aggregation/setWindowFields/ · corroborated independently at https://studio3t.com/whats-new/what-is-setwindowfields-and-why-is-it-so-neat/ [source]
- **S2. Three top-level operands.** Optional `partitionBy` (an expression), optional `sortBy` (a document of field/direction pairs, same syntax as `$sort`), required `output` (a document mapping new field names to window operators). `[M-A1] [P-2]` — https://www.mongodb.com/docs/manual/reference/operator/aggregation/setWindowFields/ [source]
- **S7. The stage does not guarantee output order.** "The `$setWindowFields` stage doesn't guarantee the order of the returned documents." `sortBy` orders the *window computation*, not the result set. A downstream `$sort` is required if the caller depends on order. Documented this way since 5.0 and unchanged in the current manual. `[M-A6] [H-16] [E-B1] [P-16]` — all four reports — https://www.mongodb.com/docs/manual/reference/operator/aggregation/setWindowFields/ · https://www.mongodb.com/docs/v5.0/reference/operator/aggregation/setWindowFields.md [source]
- **S26. `getValue()` takes an *optional* current-document `Value`.** "Some window functions implementations do not need the input Value of the current document and expect to be able to be called without it. Other window functions require this input Value and can assert this value present." This is how row-relative operators (`$rank`, `$shift`) share an interface with frame-aggregate operators. `[M-D3]` — https://raw.githubusercontent.com/mongodb/mongo/master/src/mongo/db/pipeline/window_function/window_function.h [source]
- **S31. The design was explicitly grounded in the SQL window-function literature.** Six Jira tasks created 2020-10-15 are titled `Read "Efficient Processing of Window Functions in Analytical SQL Queries"` (SERVER-84959, SERVER-84971, SERVER-85036, SERVER-85049, SERVER-85073, SERVER-85087). SERVER-84959 resolved 2020-10-22 and links the paper. `[H-2]` — https://jira.mongodb.org/browse/SERVER-84959 [source]
- **S36. The stage was deliberately excluded from Stable API V1 at launch.** SERVER-56160 (created 2021-04-19, resolved 2021-04-20, fixVersion `5.0.0-rc0`) gives the reason verbatim: "The window functions are considered somewhat unstable while we validate with the beta program whether some of our design and semantic choices were reasonable." `[H-17]` — https://jira.mongodb.org/browse/SERVER-56160 [source]
- | Version | Change | Provenance | |---|---|---| | 5.2 | `$locf` added; only usable inside `$setWindowFields` | `[H-18] [P-8]` | | 5.3 | `$linearFill` added; requires `sortBy`; errors on repeated `sortBy` values within a partition | `[H-19]` | | 5.3 | Transactions and `"snapshot"` read concern permitted (S10) | `[H-20] [M-F3] [E-A10] [P-9]` | | 5.3 | `usedDisk` explain/profiler indicator introduced | `[E-C4] [P-19]` | | 6.0 | Stage and its 5.0-era operators added to Stable API V1 | `[H-21]` | | 6.0 | `allowDiskUseByDefault` defaults to allowing spilling | `[M-F7] [H-26] [E-C3] [P-18]` | | 7.0 | [source]
- **S41. Range windows: all `sortBy` values must be numbers, exactly one `sortBy` field, ascending only.** Multi-field sort, descending sort, or non-numeric sort values are rejected. `[M-E4] [E-A1] [P-12]` — https://www.mongodb.com/docs/v8.0/reference/operator/aggregation/setwindowfields/ [source]
- **S66. The open-source DocumentDB MQL reimplementation supports most window operators but not all.** It documents `$median` and `$percentile` as "not yet supported" as window operators, and states "Collation is not supported in `$setWindowFields`." `[E-D1] [P-33]` — https://documentdb.io/docs/reference/operators/aggregation/$setwindowfields/ [source]
- **S68. The SQL frame-mode mapping is unsourced interpretation.** MongoDB's `documents` window corresponds to SQL `ROWS BETWEEN` and its `range` window to SQL `RANGE BETWEEN`, with `unit` playing the role of SQL interval offsets. The history report states plainly that **no source states this mapping**; it is a reading of the two syntaxes side by side. Carried here at the same confidence — useful, unsourced. `[H-interpretation]` — https://www.mongodb.com/docs/manual/reference/operator/aggregation/setWindowFields/ [source]
- 43. Leis, Kundhikanjana, Kemper, Neumann — "Efficient Processing of Window Functions in Analytical SQL Queries", PVLDB 8(10), 2015 — https://www.vldb.org/pvldb/vol8/p1058-leis.pdf 44. Eisenberg et al. — "SQL:2003 Has Been Published", ACM SIGMOD Record, March 2004 — https://dl.acm.org/doi/pdf/10.1145/974121.974142 45. SQL:2003 overview (window functions, SQL:1999 OLAP amendment) — https://en.wikipedia.org/wiki/SQL:2003 [source]
- **D4.** `WindowFunctionState` carries a `SimpleMemoryUsageTracker` with a configurable `maxAllowedMemoryUsageBytes`, so accumulated operator state (not just buffered documents) is metered. — https://raw.githubusercontent.com/mongodb/mongo/master/src/mongo/db/pipeline/window_function/window_function.h [source]
- **A1. Range windows require all `sortBy` values to be numbers, exactly one `sortBy` field, and ascending sort.** A range window over a multi-field sort, a descending sort, or non-numeric sort values is rejected. [source]
- **A2. Time-range windows require all `sortBy` values to be dates, and numeric boundary values must be integers.** A window of 2 hours is accepted; a window of 1.5 hours is not. [source]
- **A8. `$integral` couples `unit` to the `sortBy` type in both directions**: "If you specify a `unit`, you must specify a date in the `sortBy` field," and "If the `sortBy` field is not a date, you must omit a `unit`." Valid units are `week`, `day`, `hour`, `minute`, `second`, `millisecond` — note that `year`, `quarter`, and `month` are valid for a time-range window but not for `$integral`. [source]
- **A10. Before MongoDB 5.3, `$setWindowFields` could not be used inside transactions or with `"snapshot"` read concern.** From 5.3 onward both are supported. Code targeting 5.0–5.2 fails where the same pipeline succeeds on 5.3+. [source]
- **C5. `peakTrackedMemBytes` is reported both per query and per blocking stage.** "The explain execution statistics provide the peak memory for the entire query and also for each blocking stage. If there is only one blocking stage, the query and stage `peakTrackedMemBytes` values are the same" — so a pipeline with a `$sort` *and* a `$setWindowFields` needs the stage-level value, not the top-level one, to attribute memory correctly. Sources: https://www.mongodb.com/docs/manual/reference/explain-results/ · https://www.mongodb.com/docs/manual/reference/operator/aggregation/setWindowFields/ [source]
- **U3. Whether an index can serve the `$setWindowFields` `sortBy` is asserted by secondary sources but absent from the official documentation.** Practitioner guidance recommends a compound index on `(partitionBy, sortBy)` to avoid a collection scan. No statement in the MongoDB manual pages reviewed confirms that `$setWindowFields` consumes an index for its internal sort, and the `$setWindowFields` page's own restrictions and behaviour sections are silent on indexing. **This is a disconfirming gap: the commonly repeated optimisation advice is not vendor-documented.** [source]
- 5. The SQL-side history is that OLAP capabilities were added in SQL:1999 and extended with a window function in SQL:2003, which was published around March 2004 (per the cited Eisenberg et al. SIGMOD Record article "SQL:2003 Has Been Published"). <https://en.wikipedia.org/wiki/SQL:2003> · <https://dl.acm.org/doi/pdf/10.1145/974121.974142> [source]
- 7. The stage skeleton landed in the 4.9 development series (the pre-release line that became 5.0): SERVER-53396 "Create skeleton window function agg stage and IDL spec" was created 2020-12-16, resolved 2021-01-11, fixVersion `4.9.0`. <https://jira.mongodb.org/browse/SERVER-53396> [source]
- 10. The current server source still reflects the two-stage design: it registers the user-facing `setWindowFields` lite-parsed stage and an internal `_internalSetWindowFields` document source. <https://raw.githubusercontent.com/mongodb/mongo/master/src/mongo/db/pipeline/document_source_set_window_fields.cpp> [source]
- 11. `$setWindowFields` is annotated "New in version 5.0" in the MongoDB manual, both in the archived 5.0 manual and in the current manual. <https://www.mongodb.com/docs/v5.0/reference/operator/aggregation/setWindowFields.md> · <https://www.mongodb.com/docs/manual/reference/operator/aggregation/setWindowFields/> [source]
- 13. The 5.0 release notes present the stage under a "Window Operators" heading and list among its uses "Analysis of complex time series information without exporting the data to an external database" — the same release that introduced time series collections. <https://www.mongodb.com/docs/v5.0/release-notes/5.0.md> [source]
- 14. The operator set at 5.0 was: accumulators `$addToSet`, `$avg`, `$count`, `$covariancePop`, `$covarianceSamp`, `$derivative`, `$expMovingAvg`, `$integral`, `$max`, `$min`, `$push`, `$stdDevSamp`, `$stdDevPop`, `$sum`; order operators `$first`, `$last`, `$shift`; rank operators `$denseRank`, `$documentNumber`, `$rank`. <https://www.mongodb.com/docs/v5.0/reference/operator/aggregation/setWindowFields.md> [source]
- 16. From 5.0 onward the documentation warns that "The `$setWindowFields` stage doesn't guarantee the order of the returned documents." The current manual repeats this. <https://www.mongodb.com/docs/v5.0/reference/operator/aggregation/setWindowFields.md> · <https://www.mongodb.com/docs/manual/reference/operator/aggregation/setWindowFields/> [source]
- 18. `$locf` (last observation carried forward) is "New in version 5.2" and is only available inside `$setWindowFields`. <https://www.mongodb.com/docs/manual/reference/operator/aggregation/locf.md> [source]
- 19. `$linearFill` (linear interpolation of gaps) is "New in version 5.3", is only available inside `$setWindowFields`, requires `sortBy`, and errors on repeated `sortBy` values within a partition. <https://www.mongodb.com/docs/manual/reference/operator/aggregation/linearFill.md> [source]
- 20. Starting in MongoDB 5.3 the stage can be used within transactions and with `"snapshot"` read concern; before 5.3 both were prohibited. <https://www.mongodb.com/docs/manual/reference/operator/aggregation/setWindowFields.md> [source]
- 23. The `$concatArrays` and `$setUnion` accumulators were added to Stable API V1 in MongoDB 8.1, and appear in the current window-operator list. <https://www.mongodb.com/docs/manual/reference/stable-api-changelog.md> · <https://www.mongodb.com/docs/manual/reference/operator/aggregation/setWindowFields/> [source]
- 24. `$minMaxScaler` is "New in version 8.2", is only available inside `$setWindowFields`, and normalizes a numeric expression to a `[min, max]` range (default `[0, 1]`). <https://www.mongodb.com/docs/manual/reference/operator/aggregation/minMaxScaler.md> [source]
- 25. Starting in MongoDB 8.3, `explain()` on a `$setWindowFields` operation reports `peakTrackedMemBytes`, the maximum tracked memory in use. <https://www.mongodb.com/docs/manual/reference/operator/aggregation/setWindowFields/> [source]
- - **Interpretation, not a sourced claim.** MongoDB's `documents` window corresponds to SQL's `ROWS BETWEEN` frame and its `range` window to SQL's `RANGE BETWEEN`, with the `unit` option playing the role of SQL interval offsets. No source states this mapping explicitly; it is my reading of the two syntaxes side by side. [source]
- **A3.** With `partitionBy` omitted, the entire input is a single partition. Calculations inside each partition are independent of other partitions. — https://www.mongodb.com/docs/manual/reference/operator/aggregation/setWindowFields/ [source]
- **A5.** The stage was introduced in MongoDB 5.0. — https://www.mongodb.com/docs/manual/reference/operator/aggregation/setWindowFields/ — corroborated: https://www.percona.com/blog/window-functions-in-mongodb-5-0/ [source]
- **B1.** `$setWindowFields` is not a single execution stage. It desugars into a combination of projection, sorting, and an internal stage named `$_internalSetWindowFields`. — https://raw.githubusercontent.com/mongodb/mongo/master/src/mongo/db/pipeline/document_source_set_window_fields.h [source]
- **C1.** The internal stage buffers the current partition in a `SpillableDeque` named `_cache` and tracks a current position (`_indexOfCurrentInPartition`), exposing random access relative to that position via `operator[]`. The window is therefore a sliding view over a buffered deque, not a re-scan of the collection. — https://raw.githubusercontent.com/mongodb/mongo/master/src/mongo/db/pipeline/window_function/partition_iterator.h [source]
- **C3.** Different output fields get different expiry policies — `kDefaultSequential` expires an index as soon as it is read, `kEndpoints` / `kRightEndpoint` defer expiry to `releaseExpired()`, and `kManual` gives the caller control. A single unbounded output field therefore pins the whole partition in the buffer regardless of how tight the other windows are. — https://raw.githubusercontent.com/mongodb/mongo/master/src/mongo/db/pipeline/window_function/partition_iterator.h [source]
- **E9.** A `range` window in practice indexes relative time: Percona's worked COVID example uses `range: [-1, -1], unit: "day"` to read exactly the previous day's value and `range: [-6, 0]` for a 7-day moving average — i.e. the previous document and the previous *day* are different addresses, and only `range` expresses the second. — https://www.percona.com/blog/window-functions-in-mongodb-5-0/ [source]
- **F8.** Spilling is not historically bug-free: SERVER-99887, fixed in the 8.0 line, addressed `$setWindowFields` failing while spilling to disk. — https://www.mongodb.com/docs/manual/release-notes/8.0-changelog/ [source]
- **F9.** Observability of the stage's memory has improved recently. From MongoDB 8.2 spill statistics (`spills`, `spilledBytes`, `spilledRecords`, `spilledDataStorageSize`) are standardised per stage in explain; from 8.3 `explain` on a `$setWindowFields` operation includes `peakTrackedMemBytes`, "the maximum number of bytes of tracked memory in use." — https://www.mongodb.com/docs/manual/reference/operator/aggregation/setWindowFields/ — https://www.mongodb.com/docs/manual/release-notes/8.3/ [source]
- **U1 — Can the generated sort be served by an index?** A third-party tutorial states that `$setWindowFields` "is compiled to C++ and can use indexes on the sortBy field" (https://oneuptime.com/blog/post/2026-03-31-mongodb-setwindowfields/view), and a second page from the same host repeats that it "uses an internal sort but can leverage indexes" (https://oneuptime.com/blog/post/2026-03-31-mongodb-how-to-avoid-blocking-sort-stages-in-mongodb-aggregation/view). The server source shows the desugaring unconditionally inserting a `$sort` on `[partition key, sortBy fields]` whenever either exists (ht [source]
- **Concept:** `$setWindowFields` (MongoDB aggregation stage) **Parent domain:** mongodb-time-series **Date compiled:** 2026-09-18 [source]
- 5. Adding `unit` (`"year"` … `"millisecond"`) turns a `range` frame into a time-range frame evaluated against date values, which is the construct that expresses "the trailing 1 month of readings for this sensor" directly in the query. — https://www.mongodb.com/docs/manual/reference/operator/aggregation/setWindowFields.md [source]
- 6. The current operator set spans accumulators (`$avg`, `$sum`, `$stdDevPop/Samp`, `$covariancePop/Samp`, `$median`, `$percentile`, `$top/$topN`, `$bottom/$bottomN`, `$minN/$maxN`, `$firstN/$lastN`, `$push`, `$addToSet`, `$concatArrays`, `$setUnion`, `$mergeObjects`), time-series analytics (`$derivative`, `$integral`, `$expMovingAvg`), gap filling (`$locf`, `$linearFill`), order access (`$first`, `$last`, `$shift`), ranking (`$rank`, `$denseRank`, `$documentNumber`), and range scaling (`$minMaxScaler`). — https://www.mongodb.com/docs/manual/reference/operator/aggregation/setWindowFields.md [source]
- 8. `$expMovingAvg` is "New in version 5.0"; `$locf` is "New in version 5.2"; `$minMaxScaler` is "New in version 8.2". An `explain()` field `peakTrackedMemBytes` reporting the stage's maximum tracked memory is "New in version 8.3". — https://www.mongodb.com/docs/manual/reference/operator/aggregation/expMovingAvg.md — https://www.mongodb.com/docs/manual/reference/operator/aggregation/locf.md — https://www.mongodb.com/docs/manual/reference/operator/aggregation/minmaxscaler.md — https://www.mongodb.com/docs/manual/reference/operator/aggregation/setWindowFields.md [source]
- 21. From MongoDB 8.3, `explain()` on a `$setWindowFields` operation reports `peakTrackedMemBytes`, giving a per-operation memory figure that previously had to be inferred from spill logs. — https://www.mongodb.com/docs/manual/reference/operator/aggregation/setWindowFields.md [source]
- 32. `$setWindowFields` fills values but never creates rows. Producing a regular-interval series first requires `$densify` (new in 5.1), which is capped by `internalQueryMaxAllowedDensifyDocs` at 500,000 generated documents by default and which "does not guarantee sort order of the documents it outputs". — https://www.mongodb.com/docs/manual/reference/operator/aggregation/densify.md [source]
- **S6. Adding `unit` turns a `range` frame into a time-range frame.** Units run year/quarter/month/week/day/hour/minute/second/millisecond. `[M-E5] [P-5] [H-15]` — https://www.mongodb.com/docs/manual/reference/operator/aggregation/setWindowFields/ [source]
- **S10. From 5.3 the stage works inside transactions and with `"snapshot"` read concern**; before 5.3 both were prohibited. A pipeline valid on 5.3+ fails on 5.0–5.2. `[M-F3] [H-20] [E-A10] [P-9]` — https://www.mongodb.com/docs/manual/reference/operator/aggregation/setWindowFields/ [source]
- **S11. `$setWindowFields` desugars.** It is a user-facing lite-parsed stage that `create()` expands into, in order: (1) an optional `$set` binding a complex `partitionBy` expression to the reserved field `"__internal_setWindowFields_partition_key"`; (2) an optional `$sort`; (3) the real execution stage `$_internalSetWindowFields`; (4) an optional `$unset` dropping the temporary key. `[M-B1,B2]` — https://raw.githubusercontent.com/mongodb/mongo/master/src/mongo/db/pipeline/document_source_set_window_fields.h · https://raw.githubusercontent.com/mongodb/mongo/master/src/mongo/db/pipeline/document [source]
- **S17. The current partition is buffered in a `SpillableDeque`.** `PartitionIterator` holds `_cache` plus a current position `_indexOfCurrentInPartition` and exposes random access relative to that position via `operator[]`. A window is a sliding view over a buffered deque, not a re-scan of the collection. `[M-C1]` — https://raw.githubusercontent.com/mongodb/mongo/master/src/mongo/db/pipeline/window_function/partition_iterator.h [source]
- **S23. Memory tracking shipped with the original build-out.** SERVER-54142 "Add memory usage tracking to `$setWindowFields`" was created 2021-01-29 with fixVersion `4.9.0`; SERVER-55789 "Add explain metric for peak memory usage of `$setWindowFields` stage" carries fixVersion `5.0.0-rc0`. Metering is not a retrofit. `[H-27]` — https://jira.mongodb.org/browse/SERVER-54142 · https://jira.mongodb.org/browse/SERVER-55789 [source]
- **S33. SQL lineage behind that.** OLAP capabilities were added in SQL:1999 and extended with a window function in SQL:2003, published around March 2004. `[H-5]` — https://en.wikipedia.org/wiki/SQL:2003 · https://dl.acm.org/doi/pdf/10.1145/974121.974142 [source]
- **S37. Operator set at 5.0.** Accumulators `$addToSet`, `$avg`, `$count`, `$covariancePop`, `$covarianceSamp`, `$derivative`, `$expMovingAvg`, `$integral`, `$max`, `$min`, `$push`, `$stdDevSamp`, `$stdDevPop`, `$sum`; order operators `$first`, `$last`, `$shift`; rank operators `$denseRank`, `$documentNumber`, `$rank`. `[H-14]` — https://www.mongodb.com/docs/v5.0/reference/operator/aggregation/setWindowFields.md [source]
- **S57. A single large partition is the practical boundary.** Partitioning is what bounds the working set (S17: the buffer holds *the current partition*), and omitting `partitionBy` defaults to one partition over the entire collection (S3). The unbounded-frame default (S4) compounds it. `[E-C2] [M-C1] [P-20]` — https://www.mongodb.com/docs/manual/core/aggregation-pipeline-limits/ · https://www.mongodb.com/docs/v8.0/reference/operator/aggregation/setwindowfields/ [source]
- **S60. `peakTrackedMemBytes` is reported both per query and per blocking stage.** "If there is only one blocking stage, the query and stage `peakTrackedMemBytes` values are the same" — so a pipeline with both a `$sort` and a `$setWindowFields` needs the *stage-level* value to attribute memory correctly. `[E-C5]` — https://www.mongodb.com/docs/manual/reference/explain-results/ [source]
- **S61. Spilling has a bug history.** SERVER-99887, fixed in the 8.0 line, addressed `$setWindowFields` failing while spilling to disk. `[M-F8]` — https://www.mongodb.com/docs/manual/release-notes/8.0-changelog/ [source]
- **Position A — "yes, it uses indexes."** A third-party tutorial states `$setWindowFields` "is compiled to C++ and can use indexes on the sortBy field," and a second page from the same host repeats that it "uses an internal sort but can leverage indexes." `[M-U1]` — https://oneuptime.com/blog/post/2026-03-31-mongodb-setwindowfields/view · https://oneuptime.com/blog/post/2026-03-31-mongodb-how-to-avoid-blocking-sort-stages-in-mongodb-aggregation/view [source]
- **Position B — "not vendor-documented; treat as unproven."** No MongoDB manual page reviewed by any of the four reports confirms the stage consumes an index for its internal sort, and the `$setWindowFields` page's restrictions and behaviour sections are silent on indexing. The edge-cases report classes this explicitly as **a disconfirming gap: commonly repeated optimisation advice that is not vendor-documented.** `[E-U3]` — https://www.mongodb.com/docs/manual/reference/operator/aggregation/setWindowFields/ [source]
- **Synthesis verdict:** the safe reading is Position B. Assume a `$setWindowFields` with a `partitionBy` and a `sortBy` performs a blocking sort unless a compound index on exactly that key order exists ahead of it. Positions A/A′ describe a real possibility on regular collections but neither states the covering condition, and A′ is the run's lowest-confidence source. **Settle it per-deployment by reading the explain plan; nobody in this run did.** [source]
- **Docs and source agree:** the Stable API changelog states `$setWindowFields` was added to Stable API V1 in MongoDB 6.0, and the current server source registers the stage with `AllowedWithApiStrict::kAlways`. [source]
- **The ticket disagrees:** SERVER-56161 "Add `$setWindowFields` to API Version 1" is still listed **Unresolved** with no fixVersion, and no resolved ticket recording the 6.0 inclusion was found. [source]
Related concepts
- setWindowFields — is a part of $setWindowFields Window Functions
- Window — is a part of $setWindowFields Window Functions
- Functions — is a part of $setWindowFields Window Functions
Children
- No children recorded.