> For the complete MongoDB documentation index, see www.mongodb.com/docs/llms.txt

<!--
Tab options on this page. Append to the .md URL to filter:
  ?tabs=<id,...>   select specific tabs (e.g. ?tabs=nodejs,shell)
  ?allTabs=true    include every tab
  (no param)       default: one tab per tabset

Available tabs:
  drivers: shell, csharp, nodejs
-->

# $setWindowFields (aggregation stage)

## Definition

**New in version 5.0**

Performs operations on a specified span of documents in a collection, known as a *window*, and returns the results based on the chosen [window operator.](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setwindowfields.md#std-label-setWindowFields-window-operators)

For example, you can use the [`$setWindowFields`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setwindowfields.md#mongodb-pipeline-pipe.-setWindowFields) stage to output the:

- Difference in sales between two documents in a collection.

- Sales rankings.

- Cumulative sales totals.

- Analysis of complex time series information without exporting the data to an external database.

## Syntax

The [`$setWindowFields`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setwindowfields.md#mongodb-pipeline-pipe.-setWindowFields) stage syntax:

```none
{
   $setWindowFields: {
      partitionBy: <expression>,
      sortBy: {
         <sort field 1>: <sort order>,
         <sort field 2>: <sort order>,
         ...,
         <sort field n>: <sort order>
      },
      output: {
         <output field 1>: {
            <window operator>: <window operator parameters>,
            window: {
               documents: [ <lower boundary>, <upper boundary> ],
               range: [ <lower boundary>, <upper boundary> ],
               unit: <time unit>
            }
         },
         <output field 2>: { ... },
         ...
         <output field n>: { ... }
      }
   }
}
```

The [`$setWindowFields`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setwindowfields.md#mongodb-pipeline-pipe.-setWindowFields) stage takes a document with these fields:

| Field | Necessity | Description |
| --- | --- | --- |
| [partitionBy](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setwindowfields.md#std-label-setWindowFields-partitionBy) | Optional | Specifies an [expression](https://www.mongodb.com/docs/manual/reference/mql/expressions.md#std-label-aggregation-expressions) to group the documents. In the [`$setWindowFields`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setwindowfields.md#mongodb-pipeline-pipe.-setWindowFields) stage, the group of documents is known as a *partition*. Default is one partition for the entire collection. |
| [sortBy](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setwindowfields.md#std-label-setWindowFields-sortBy) | Required for some operators (see [Restrictions)](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setwindowfields.md#std-label-setWindowFields-restrictions) | Specifies the field(s) to sort the documents by in the partition. Uses the same syntax as the [`$sort`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/sort.md#mongodb-pipeline-pipe.-sort) stage. Default is no sorting. |
| [output](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setwindowfields.md#std-label-setWindowFields-output) | Required | Specifies the field(s) to append to the documents in the output returned by the [`$setWindowFields`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setwindowfields.md#mongodb-pipeline-pipe.-setWindowFields) stage. Each field is set to the result returned by the [window operator.](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setwindowfields.md#std-label-setWindowFields-window-operators) A field can contain [dots](https://www.mongodb.com/docs/manual/core/document.md#std-label-document-dot-notation) to specify embedded document fields and array fields. The semantics for the embedded document dotted notation in the [`$setWindowFields`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setwindowfields.md#mongodb-pipeline-pipe.-setWindowFields) stage are the same as the [`$addFields`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/addfields.md#mongodb-pipeline-pipe.-addFields) and [`$set`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/set.md#mongodb-pipeline-pipe.-set) stages. See [embedded document $addFields example](https://www.mongodb.com/docs/manual/reference/operator/aggregation/addfields.md#std-label-add-field-to-embedded) and [embedded document $set example.](https://www.mongodb.com/docs/manual/reference/operator/aggregation/set.md#std-label-set-add-field-to-embedded) The `window operator` is the [window operator](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setwindowfields.md#std-label-setWindowFields-window-operators) name to use in the [`$setWindowFields`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setwindowfields.md#mongodb-pipeline-pipe.-setWindowFields) stage.; The `window operator parameters` are the parameters to pass to the [window operator.](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setwindowfields.md#std-label-setWindowFields-window-operators) |
| [window](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setwindowfields.md#std-label-setWindowFields-window) | Optional | Specifies the window boundaries and parameters. Window boundaries are inclusive. Default is an unbounded window, which includes all documents in the partition. Specify either a [documents](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setwindowfields.md#std-label-setWindowFields-documents) or [range](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setwindowfields.md#std-label-setWindowFields-range) window. |
| [documents](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setwindowfields.md#std-label-setWindowFields-documents) | Optional | A window where the lower and upper boundaries are specified relative to the position of the current document read from the collection. The window boundaries are specified using a two element array containing a lower and upper limit string or integer. Use: The `"current"` string for the current document position in the output.; The `"unbounded"` string for the first or last document position in the partition.; An integer for a position relative to the current document. Use a negative integer for a position before the current document. Use a positive integer for a position after the current document. `0` is the current document position. See [Documents Window Examples.](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setwindowfields.md#std-label-setWindowFields-documents-window-examples) |
| [range](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setwindowfields.md#std-label-setWindowFields-range) | Optional | A window where the lower and upper boundaries are defined using a range of values based on the [sortBy](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setwindowfields.md#std-label-setWindowFields-sortBy) field in the current document. The window boundaries are specified using a two element array containing a lower and upper limit string or number. Use: The `"current"` string for the current document position in the output.; The `"unbounded"` string for the first or last document position in the partition.; A number to add to the value of the [sortBy](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setwindowfields.md#std-label-setWindowFields-sortBy) field for the current document. A document is in the window if the [sortBy](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setwindowfields.md#std-label-setWindowFields-sortBy) field value is inclusively within the lower and upper boundaries. See [Range Window Example.](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setwindowfields.md#std-label-setWindowFields-range-window-example) |
| [unit](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setwindowfields.md#std-label-setWindowFields-unit) | Optional | Specifies the units for time [range](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setwindowfields.md#std-label-setWindowFields-range) window boundaries. Can be set to one of these strings: `"year"`; `"quarter"`; `"month"`; `"week"`; `"day"`; `"hour"`; `"minute"`; `"second"`; `"millisecond"` If omitted, default numeric [range](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setwindowfields.md#std-label-setWindowFields-range) window boundaries are used. See [Time Range Window Examples.](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setwindowfields.md#std-label-setWindowFields-time-range-window-examples) |

**See also:**

[Examples](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setwindowfields.md#std-label-setWindowFields-examples)

## Behavior

The [`$setWindowFields`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setwindowfields.md#mongodb-pipeline-pipe.-setWindowFields) stage appends new fields to existing documents. You can include one or more [`$setWindowFields`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setwindowfields.md#mongodb-pipeline-pipe.-setWindowFields) stages in an aggregation operation.

Starting in MongoDB 5.3, you can use the [`$setWindowFields`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setwindowfields.md#mongodb-pipeline-pipe.-setWindowFields) stage with [transactions](https://www.mongodb.com/docs/manual/core/transactions.md#std-label-transactions) and the [`"snapshot"`](https://www.mongodb.com/docs/manual/reference/read-concern-snapshot.md#mongodb-readconcern-readconcern.-snapshot-) read concern.

The `$setWindowFields` stage doesn't guarantee the order of the returned documents.

## Window Operators

These operators can be used with the [`$setWindowFields`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setwindowfields.md#mongodb-pipeline-pipe.-setWindowFields) stage:

- Accumulator operators: [`$addToSet`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/addtoset.md#mongodb-group-grp.-addToSet), [`$avg`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/avg.md#mongodb-group-grp.-avg), [`$bottom`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/bottom.md#mongodb-group-grp.-bottom), [`$bottomN`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/bottomn.md#mongodb-group-grp.-bottomN), [`$concatArrays`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/concatarrays.md#mongodb-group-grp.-concatArrays), [`$count`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/count-accumulator.md#mongodb-group-grp.-count), [`$covariancePop`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/covariancepop.md#mongodb-group-grp.-covariancePop), [`$covarianceSamp`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/covariancesamp.md#mongodb-group-grp.-covarianceSamp), [`$derivative`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/derivative.md#mongodb-group-grp.-derivative), [`$expMovingAvg`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/expmovingavg.md#mongodb-group-grp.-expMovingAvg), [`$firstN`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/firstn.md#mongodb-group-grp.-firstN), [`$integral`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/integral.md#mongodb-group-grp.-integral), [`$lastN`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/lastn.md#mongodb-group-grp.-lastN), [`$max`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/max.md#mongodb-group-grp.-max), [`$maxN`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/maxn.md#mongodb-group-grp.-maxN), [`$median`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/median.md#mongodb-group-grp.-median), [`$mergeObjects`](https://www.mongodb.com/docs/manual/reference/mql/window-functions/mergeobjects.md#mongodb-window-window.-mergeObjects), [`$min`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/min.md#mongodb-group-grp.-min), [`$minN`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/minn.md#mongodb-group-grp.-minN), [`$percentile`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/percentile.md#mongodb-group-grp.-percentile), [`$push`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/push.md#mongodb-group-grp.-push), [`$setUnion`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setunion.md#mongodb-group-grp.-setUnion), [`$stdDevSamp`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/stddevsamp.md#mongodb-group-grp.-stdDevSamp), [`$stdDevPop`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/stddevpop.md#mongodb-group-grp.-stdDevPop), [`$sum`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/sum.md#mongodb-group-grp.-sum), [`$top`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/top.md#mongodb-group-grp.-top), [`$topN`.](https://www.mongodb.com/docs/manual/reference/operator/aggregation/topn.md#mongodb-group-grp.-topN)

* Gap filling operators: [`$linearFill`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/linearfill.md#mongodb-group-grp.-linearFill) and [`$locf`.](https://www.mongodb.com/docs/manual/reference/operator/aggregation/locf.md#mongodb-group-grp.-locf)

- Order operators: [`$first`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/first.md#mongodb-group-grp.-first), [`$last`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/last.md#mongodb-group-grp.-last), and [`$shift`.](https://www.mongodb.com/docs/manual/reference/operator/aggregation/shift.md#mongodb-group-grp.-shift)

* Rank operators: [`$denseRank`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/denserank.md#mongodb-group-grp.-denseRank), [`$documentNumber`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/documentnumber.md#mongodb-group-grp.-documentNumber), and [`$rank`.](https://www.mongodb.com/docs/manual/reference/operator/aggregation/rank.md#mongodb-group-grp.-rank)

* Range operator: [`$minMaxScaler`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/minmaxscaler.md#mongodb-group-grp.-minMaxScaler)

## Explain Output

**New in version 8.3**

If you run [`explain`](https://www.mongodb.com/docs/manual/reference/command/explain.md#mongodb-dbcommand-dbcmd.explain) on a `$setWindowsFields` operation, the output contains a `peakTrackedMemBytes` field that contains the maximum number of bytes of tracked memory in use. For more information, see [`explain.executionStats.peakTrackedMemBytes`.](https://www.mongodb.com/docs/manual/reference/explain-results.md#mongodb-data-explain.executionStats.peakTrackedMemBytes)

## Restrictions

Restrictions for the [`$setWindowFields`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setwindowfields.md#mongodb-pipeline-pipe.-setWindowFields) stage:

- Before MongoDB 5.3, the [`$setWindowFields`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setwindowfields.md#mongodb-pipeline-pipe.-setWindowFields) stage cannot be used:

  - Within [transactions.](https://www.mongodb.com/docs/manual/core/transactions.md#std-label-transactions)

  - With [`"snapshot"`](https://www.mongodb.com/docs/manual/reference/read-concern-snapshot.md#mongodb-readconcern-readconcern.-snapshot-) read concern.

- [sortBy](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setwindowfields.md#std-label-setWindowFields-sortBy) is required for:

  - [Rank](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setwindowfields.md#std-label-setWindowFields-rank-operators) and [order](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setwindowfields.md#std-label-setWindowFields-order-operators) window operators.

  - Bounded windows (either a [documents](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setwindowfields.md#std-label-setWindowFields-documents) window or a [range](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setwindowfields.md#std-label-setWindowFields-range) window).

  - [`$linearFill`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/linearfill.md#mongodb-group-grp.-linearFill) operator.

- [Range](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setwindowfields.md#std-label-setWindowFields-range) windows require all [sortBy](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setwindowfields.md#std-label-setWindowFields-sortBy) values to be numbers.

- [Time range](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setwindowfields.md#std-label-setWindowFields-unit) windows require all [sortBy](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setwindowfields.md#std-label-setWindowFields-sortBy) values to be dates.

- [Range](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setwindowfields.md#std-label-setWindowFields-range) and [time range](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setwindowfields.md#std-label-setWindowFields-unit) windows can only contain one [sortBy](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setwindowfields.md#std-label-setWindowFields-sortBy) field and the sort must be ascending.

- You cannot specify both a [documents](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setwindowfields.md#std-label-setWindowFields-documents) window and a [range](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setwindowfields.md#std-label-setWindowFields-range) window.

- These operators use an implicit window and return an error if you specify a [window](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setwindowfields.md#std-label-setWindowFields-window) option:

  - [Rank](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setwindowfields.md#std-label-setWindowFields-rank-operators) operators.

  - [`$shift`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/shift.md#mongodb-group-grp.-shift) operator.

- For [range](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setwindowfields.md#std-label-setWindowFields-range) windows, only numbers in the specified range are included in the window. Missing, undefined, and `null` values are excluded.

- For [time range](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setwindowfields.md#std-label-setWindowFields-unit) windows:

  - Only date and time types are included in the window.

  - Numeric boundary values must be integers. For example, you can use 2 hours as a boundary but you cannot use 1.5 hours.

- For empty windows or windows with incompatible values (for example, using [`$sum`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/sum.md#mongodb-group-grp.-sum) on strings), the returned value depends on the operator:

  - For [`$count`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/count-accumulator.md#mongodb-group-grp.-count) and [`$sum`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/sum.md#mongodb-group-grp.-sum), the returned value is `0`.

  - For [`$addToSet`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/addtoset.md#mongodb-group-grp.-addToSet) and [`$push`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/push.md#mongodb-group-grp.-push), the returned value is an empty array.

  - For all other operators, the returned value is `null`.

## Examples

### MongoDB Shell

Create a `cakeSales` collection that contains cake sales in the states of California (`CA`) and Washington (`WA`):

```javascript
db.cakeSales.insertMany( [
   { _id: 0, type: "chocolate", orderDate: new Date("2020-05-18T14:10:30Z"),
     state: "CA", price: 13, quantity: 120 },
   { _id: 1, type: "chocolate", orderDate: new Date("2021-03-20T11:30:05Z"),
     state: "WA", price: 14, quantity: 140 },
   { _id: 2, type: "vanilla", orderDate: new Date("2021-01-11T06:31:15Z"),
     state: "CA", price: 12, quantity: 145 },
   { _id: 3, type: "vanilla", orderDate: new Date("2020-02-08T13:13:23Z"),
     state: "WA", price: 13, quantity: 104 },
   { _id: 4, type: "strawberry", orderDate: new Date("2019-05-18T16:09:01Z"),
     state: "CA", price: 41, quantity: 162 },
   { _id: 5, type: "strawberry", orderDate: new Date("2019-01-08T06:12:03Z"),
     state: "WA", price: 43, quantity: 134 }
] )

```

The following examples use the `cakeSales` collection.

### Documents Window Examples

#### Use Documents Window to Obtain Cumulative Quantity for Each State

This example uses a [documents](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setwindowfields.md#std-label-setWindowFields-documents) window in [`$setWindowFields`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setwindowfields.md#mongodb-pipeline-pipe.-setWindowFields) to output the cumulative cake sales `quantity` for each `state`. In the example output, the `cumulativeQuantityForState` field shows the cumulative `quantity` for `CA` and `WA`.

```javascript
db.cakeSales.aggregate( [
   {
      $setWindowFields: {
         partitionBy: "$state",
         sortBy: { orderDate: 1 },
         output: {
            cumulativeQuantityForState: {
               $sum: "$quantity",
               window: {
                  documents: [ "unbounded", "current" ]
               }
            }
         }
      }
   }
] )

```

**Output:**

```javascript
[
  {
    _id: 4,
    type: 'strawberry',
    orderDate: ISODate('2019-05-18T16:09:01.000Z'),
    state: 'CA',
    price: 41,
    quantity: 162,
    cumulativeQuantityForState: 162
  },
  {
    _id: 0,
    type: 'chocolate',
    orderDate: ISODate('2020-05-18T14:10:30.000Z'),
    state: 'CA',
    price: 13,
    quantity: 120,
    cumulativeQuantityForState: 282
  },
  {
    _id: 2,
    type: 'vanilla',
    orderDate: ISODate('2021-01-11T06:31:15.000Z'),
    state: 'CA',
    price: 12,
    quantity: 145,
    cumulativeQuantityForState: 427
  },
  {
    _id: 5,
    type: 'strawberry',
    orderDate: ISODate('2019-01-08T06:12:03.000Z'),
    state: 'WA',
    price: 43,
    quantity: 134,
    cumulativeQuantityForState: 134
  },
  {
    _id: 3,
    type: 'vanilla',
    orderDate: ISODate('2020-02-08T13:13:23.000Z'),
    state: 'WA',
    price: 13,
    quantity: 104,
    cumulativeQuantityForState: 238
  },
  {
    _id: 1,
    type: 'chocolate',
    orderDate: ISODate('2021-03-20T11:30:05.000Z'),
    state: 'WA',
    price: 14,
    quantity: 140,
    cumulativeQuantityForState: 378
  }
]

```

In the example:

- `partitionBy: "$state"` [partitions](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setwindowfields.md#std-label-setWindowFields-partitionBy) the documents in the collection by `state`. There are partitions for `CA` and `WA`.

- `sortBy: { orderDate: 1 }` [sorts](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setwindowfields.md#std-label-setWindowFields-sortBy) the documents in each partition by `orderDate` in ascending order (`1`), so the earliest `orderDate` is first.

* `output`:

  - Sets the `cumulativeQuantityForState` field to the cumulative `quantity` for each `state`, which increases by successive additions to the previous value in the partition.

  - Calculates the cumulative `quantity` using the [`$sum`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/sum.md#mongodb-group-grp.-sum) operator run in a [documents](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setwindowfields.md#std-label-setWindowFields-documents) window.

    The [window](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setwindowfields.md#std-label-setWindowFields-window) contains documents between an `unbounded` lower limit and the `current` document. This means [`$sum`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/sum.md#mongodb-group-grp.-sum) returns the cumulative `quantity` for the documents between the beginning of the partition and the current document.

#### Use Documents Window to Obtain Cumulative Quantity for Each Year

This example uses a [documents](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setwindowfields.md#std-label-setWindowFields-documents) window in [`$setWindowFields`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setwindowfields.md#mongodb-pipeline-pipe.-setWindowFields) to output the cumulative cake sales `quantity` for each [`$year`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/year.md#mongodb-expression-exp.-year) in `orderDate`. In the example output, the `cumulativeQuantityForYear` field shows the cumulative `quantity` for each year.

```javascript
db.cakeSales.aggregate( [
   {
      $setWindowFields: {
         partitionBy: { $year: "$orderDate" },
         sortBy: { orderDate: 1 },
         output: {
            cumulativeQuantityForYear: {
               $sum: "$quantity",
               window: {
                  documents: [ "unbounded", "current" ]
               }
            }
         }
      }
   }
] )

```

**Output:**

```javascript
[
  {
    _id: 5,
    type: 'strawberry',
    orderDate: ISODate('2019-01-08T06:12:03.000Z'),
    state: 'WA',
    price: 43,
    quantity: 134,
    cumulativeQuantityForYear: 134
  },
  {
    _id: 4,
    type: 'strawberry',
    orderDate: ISODate('2019-05-18T16:09:01.000Z'),
    state: 'CA',
    price: 41,
    quantity: 162,
    cumulativeQuantityForYear: 296
  },
  {
    _id: 3,
    type: 'vanilla',
    orderDate: ISODate('2020-02-08T13:13:23.000Z'),
    state: 'WA',
    price: 13,
    quantity: 104,
    cumulativeQuantityForYear: 104
  },
  {
    _id: 0,
    type: 'chocolate',
    orderDate: ISODate('2020-05-18T14:10:30.000Z'),
    state: 'CA',
    price: 13,
    quantity: 120,
    cumulativeQuantityForYear: 224
  },
  {
    _id: 2,
    type: 'vanilla',
    orderDate: ISODate('2021-01-11T06:31:15.000Z'),
    state: 'CA',
    price: 12,
    quantity: 145,
    cumulativeQuantityForYear: 145
  },
  {
    _id: 1,
    type: 'chocolate',
    orderDate: ISODate('2021-03-20T11:30:05.000Z'),
    state: 'WA',
    price: 14,
    quantity: 140,
    cumulativeQuantityForYear: 285
  }
]

```

In the example:

- `partitionBy: { $year: "$orderDate" }` [partitions](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setwindowfields.md#std-label-setWindowFields-partitionBy) the documents in the collection by [`$year`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/year.md#mongodb-expression-exp.-year) in `orderDate`. There are partitions for `2019`, `2020`, and `2021`.

- `sortBy: { orderDate: 1 }` [sorts](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setwindowfields.md#std-label-setWindowFields-sortBy) the documents in each partition by `orderDate` in ascending order (`1`), so the earliest `orderDate` is first.

- `output`:

  - Sets the `cumulativeQuantityForYear` field to the cumulative `quantity` for each year, which increases by successive additions to the previous value in the partition.

  - Calculates the cumulative `quantity` using the [`$sum`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/sum.md#mongodb-group-grp.-sum) operator run in a [documents](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setwindowfields.md#std-label-setWindowFields-documents) window.

    The [window](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setwindowfields.md#std-label-setWindowFields-window) contains documents between an `unbounded` lower limit and the `current` document. This means [`$sum`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/sum.md#mongodb-group-grp.-sum) returns the cumulative `quantity` for the documents between the beginning of the partition and the current document.

#### Use Documents Window to Obtain Moving Average Quantity for Each Year

This example uses a [documents](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setwindowfields.md#std-label-setWindowFields-documents) window in [`$setWindowFields`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setwindowfields.md#mongodb-pipeline-pipe.-setWindowFields) to output the moving average for the cake sales `quantity`. In the example output, the `averageQuantity` field shows the moving average `quantity`.

```javascript
db.cakeSales.aggregate( [
   {
      $setWindowFields: {
         partitionBy: { $year: "$orderDate" },
         sortBy: { orderDate: 1 },
         output: {
            averageQuantity: {
               $avg: "$quantity",
               window: {
                  documents: [ -1, 0 ]
               }
            }
         }
      }
   }
] )

```

**Output:**

```javascript
[
  {
    _id: 5,
    type: 'strawberry',
    orderDate: ISODate('2019-01-08T06:12:03.000Z'),
    state: 'WA',
    price: 43,
    quantity: 134,
    averageQuantity: 134
  },
  {
    _id: 4,
    type: 'strawberry',
    orderDate: ISODate('2019-05-18T16:09:01.000Z'),
    state: 'CA',
    price: 41,
    quantity: 162,
    averageQuantity: 148
  },
  {
    _id: 3,
    type: 'vanilla',
    orderDate: ISODate('2020-02-08T13:13:23.000Z'),
    state: 'WA',
    price: 13,
    quantity: 104,
    averageQuantity: 104
  },
  {
    _id: 0,
    type: 'chocolate',
    orderDate: ISODate('2020-05-18T14:10:30.000Z'),
    state: 'CA',
    price: 13,
    quantity: 120,
    averageQuantity: 112
  },
  {
    _id: 2,
    type: 'vanilla',
    orderDate: ISODate('2021-01-11T06:31:15.000Z'),
    state: 'CA',
    price: 12,
    quantity: 145,
    averageQuantity: 145
  },
  {
    _id: 1,
    type: 'chocolate',
    orderDate: ISODate('2021-03-20T11:30:05.000Z'),
    state: 'WA',
    price: 14,
    quantity: 140,
    averageQuantity: 142.5
  }
]

```

In the example:

- `partitionBy: "$orderDate"` [partitions](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setwindowfields.md#std-label-setWindowFields-partitionBy) the documents in the collection by [`$year`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/year.md#mongodb-expression-exp.-year) in `orderDate`. There are partitions for `2019`, `2020`, and `2021`.

- `sortBy: { orderDate: 1 }` [sorts](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setwindowfields.md#std-label-setWindowFields-sortBy) the documents in each partition by `orderDate` in ascending order (`1`), so the earliest `orderDate` is first.

- `output`:

  - Sets the `averageQuantity` field to the moving average `quantity` for each year.

  - Calculates the moving average `quantity` using the [`$avg`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/avg.md#mongodb-group-grp.-avg) operator run in a [documents](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setwindowfields.md#std-label-setWindowFields-documents) window.

    The [window](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setwindowfields.md#std-label-setWindowFields-window) contains documents between `-1` and `0`. This means [`$avg`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/avg.md#mongodb-group-grp.-avg) returns the moving average `quantity` between the document before the current document (`-1`) and the current document (`0`) in the partition.

#### Use Documents Window to Obtain Cumulative and Maximum Quantity for Each Year

This example uses a [documents](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setwindowfields.md#std-label-setWindowFields-documents) window in [`$setWindowFields`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setwindowfields.md#mongodb-pipeline-pipe.-setWindowFields) to output the cumulative and maximum cake sales `quantity` values for each [`$year`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/year.md#mongodb-expression-exp.-year) in `orderDate`. In the example output, the `cumulativeQuantityForYear` field shows the cumulative `quantity` and the `maximumQuantityForYear` field shows the maximum `quantity`.

```javascript
db.cakeSales.aggregate( [
   {
      $setWindowFields: {
         partitionBy: { $year: "$orderDate" },
         sortBy: { orderDate: 1 },
         output: {
            cumulativeQuantityForYear: {
               $sum: "$quantity",
               window: {
                  documents: [ "unbounded", "current" ]
               }
            },
            maximumQuantityForYear: {
               $max: "$quantity",
               window: {
                  documents: [ "unbounded", "unbounded" ]
               }
            }
         }
      }
   }
] )

```

**Output:**

```javascript
[
  {
    _id: 5,
    type: 'strawberry',
    orderDate: ISODate('2019-01-08T06:12:03.000Z'),
    state: 'WA',
    price: 43,
    quantity: 134,
    cumulativeQuantityForYear: 134,
    maximumQuantityForYear: 162
  },
  {
    _id: 4,
    type: 'strawberry',
    orderDate: ISODate('2019-05-18T16:09:01.000Z'),
    state: 'CA',
    price: 41,
    quantity: 162,
    cumulativeQuantityForYear: 296,
    maximumQuantityForYear: 162
  },
  {
    _id: 3,
    type: 'vanilla',
    orderDate: ISODate('2020-02-08T13:13:23.000Z'),
    state: 'WA',
    price: 13,
    quantity: 104,
    cumulativeQuantityForYear: 104,
    maximumQuantityForYear: 120
  },
  {
    _id: 0,
    type: 'chocolate',
    orderDate: ISODate('2020-05-18T14:10:30.000Z'),
    state: 'CA',
    price: 13,
    quantity: 120,
    cumulativeQuantityForYear: 224,
    maximumQuantityForYear: 120
  },
  {
    _id: 2,
    type: 'vanilla',
    orderDate: ISODate('2021-01-11T06:31:15.000Z'),
    state: 'CA',
    price: 12,
    quantity: 145,
    cumulativeQuantityForYear: 145,
    maximumQuantityForYear: 145
  },
  {
    _id: 1,
    type: 'chocolate',
    orderDate: ISODate('2021-03-20T11:30:05.000Z'),
    state: 'WA',
    price: 14,
    quantity: 140,
    cumulativeQuantityForYear: 285,
    maximumQuantityForYear: 145
  }
]

```

In the example:

- `partitionBy: "$orderDate"` [partitions](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setwindowfields.md#std-label-setWindowFields-partitionBy) the documents in the collection by [`$year`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/year.md#mongodb-expression-exp.-year) in `orderDate`. There are partitions for `2019`, `2020`, and `2021`.

- `sortBy: { orderDate: 1 }` [sorts](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setwindowfields.md#std-label-setWindowFields-sortBy) the documents in each partition by `orderDate` in ascending order (`1`), so the earliest `orderDate` is first.

- `output`:

  - Sets the `cumulativeQuantityForYear` field to the cumulative `quantity` for each year.

  - Calculates the cumulative `quantity` using the [`$sum`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/sum.md#mongodb-group-grp.-sum) operator run in a [documents](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setwindowfields.md#std-label-setWindowFields-documents) window.

    The [window](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setwindowfields.md#std-label-setWindowFields-window) contains documents between an `unbounded` lower limit and the `current` document. This means [`$sum`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/sum.md#mongodb-group-grp.-sum) returns the cumulative quantity for the documents between the beginning of the partition and the current document.

  - Sets the `maximumQuantityForYear` field to the maximum `quantity` for each year.

  - Calculates the maximum `quantity` of all the documents using the [`$max`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/max.md#mongodb-group-grp.-max) operator run in a [documents](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setwindowfields.md#std-label-setWindowFields-documents) window.

    The [window](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setwindowfields.md#std-label-setWindowFields-window) contains documents between an `unbounded` lower and `upper` limit. This means [`$max`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/max.md#mongodb-group-grp.-max) returns the maximum quantity for the documents in the partition.

### Range Window Example

This example uses a [range](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setwindowfields.md#std-label-setWindowFields-range) window in [`$setWindowFields`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setwindowfields.md#mongodb-pipeline-pipe.-setWindowFields) to return the sum of the `quantity` values of cakes sold for orders within plus or minus 10 dollars of the current document's `price` value. In the example output, the `quantityFromSimilarOrders` field shows the sum of the `quantity` values for documents in the window.

```javascript
db.cakeSales.aggregate( [
   {
      $setWindowFields: {
         partitionBy: "$state",
         sortBy: { price: 1 },
         output: {
            quantityFromSimilarOrders: {
               $sum: "$quantity",
               window: {
                  range: [ -10, 10 ]
               }
            }
         }
      }
   }
] )

```

**Output:**

```javascript
[
  {
    _id: 2,
    type: 'vanilla',
    orderDate: ISODate('2021-01-11T06:31:15.000Z'),
    state: 'CA',
    price: 12,
    quantity: 145,
    quantityFromSimilarOrders: 265
  },
  {
    _id: 0,
    type: 'chocolate',
    orderDate: ISODate('2020-05-18T14:10:30.000Z'),
    state: 'CA',
    price: 13,
    quantity: 120,
    quantityFromSimilarOrders: 265
  },
  {
    _id: 4,
    type: 'strawberry',
    orderDate: ISODate('2019-05-18T16:09:01.000Z'),
    state: 'CA',
    price: 41,
    quantity: 162,
    quantityFromSimilarOrders: 162
  },
  {
    _id: 3,
    type: 'vanilla',
    orderDate: ISODate('2020-02-08T13:13:23.000Z'),
    state: 'WA',
    price: 13,
    quantity: 104,
    quantityFromSimilarOrders: 244
  },
  {
    _id: 1,
    type: 'chocolate',
    orderDate: ISODate('2021-03-20T11:30:05.000Z'),
    state: 'WA',
    price: 14,
    quantity: 140,
    quantityFromSimilarOrders: 244
  },
  {
    _id: 5,
    type: 'strawberry',
    orderDate: ISODate('2019-01-08T06:12:03.000Z'),
    state: 'WA',
    price: 43,
    quantity: 134,
    quantityFromSimilarOrders: 134
  }
]

```

In the example:

- `partitionBy: "$state"` [partitions](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setwindowfields.md#std-label-setWindowFields-partitionBy) the documents in the collection by `state`. There are partitions for `CA` and `WA`.

- `sortBy: { price: 1 }` [sorts](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setwindowfields.md#std-label-setWindowFields-sortBy) the documents in each partition by `price` in ascending order (`1`), so the lowest `price` is first.

- `output` sets the `quantityFromSimilarOrders` field to the sum of the `quantity` values from the documents in a [range](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setwindowfields.md#std-label-setWindowFields-range) window.

  - The [window](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setwindowfields.md#std-label-setWindowFields-window) contains documents between a lower limit of `-10` and an upper limit of `10`. The range is inclusive.

  - [`$sum`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/sum.md#mongodb-group-grp.-sum) returns the sum of `quantity` values contained in a range of plus or minus 10 dollars of the current document's `price` value.

### Time Range Window Examples

#### Use a Time Range Window with a Positive Upper Bound

The following example uses a [window](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setwindowfields.md#std-label-setWindowFields-window) with a positive upper bound time range [unit](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setwindowfields.md#std-label-setWindowFields-unit) in [`$setWindowFields`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setwindowfields.md#mongodb-pipeline-pipe.-setWindowFields). The pipeline outputs an array of `orderDate` values for each `state` that match the specified time range. In the example output, the `recentOrders` field shows the array of `orderDate` values for `CA` and `WA`.

```javascript
db.cakeSales.aggregate( [
   {
      $setWindowFields: {
         partitionBy: "$state",
         sortBy: { orderDate: 1 },
         output: {
            recentOrders: {
               $push: "$orderDate",
               window: {
                  range: [ "unbounded", 10 ],
                  unit: "month"
               }
            }
         }
      }
   }
] )

```

**Output:**

```javascript
[
  {
    _id: 4,
    type: 'strawberry',
    orderDate: ISODate('2019-05-18T16:09:01.000Z'),
    state: 'CA',
    price: 41,
    quantity: 162,
    recentOrders: [
      ISODate('2019-05-18T16:09:01.000Z')
    ]
  },
  {
    _id: 0,
    type: 'chocolate',
    orderDate: ISODate('2020-05-18T14:10:30.000Z'),
    state: 'CA',
    price: 13,
    quantity: 120,
    recentOrders: [
      ISODate('2019-05-18T16:09:01.000Z'),
      ISODate('2020-05-18T14:10:30.000Z'),
      ISODate('2021-01-11T06:31:15.000Z')
    ]
  },
  {
    _id: 2,
    type: 'vanilla',
    orderDate: ISODate('2021-01-11T06:31:15.000Z'),
    state: 'CA',
    price: 12,
    quantity: 145,
    recentOrders: [
      ISODate('2019-05-18T16:09:01.000Z'),
      ISODate('2020-05-18T14:10:30.000Z'),
      ISODate('2021-01-11T06:31:15.000Z')
    ]
  },
  {
    _id: 5,
    type: 'strawberry',
    orderDate: ISODate('2019-01-08T06:12:03.000Z'),
    state: 'WA',
    price: 43,
    quantity: 134,
    recentOrders: [
      ISODate('2019-01-08T06:12:03.000Z')
    ]
  },
  {
    _id: 3,
    type: 'vanilla',
    orderDate: ISODate('2020-02-08T13:13:23.000Z'),
    state: 'WA',
    price: 13,
    quantity: 104,
    recentOrders: [
      ISODate('2019-01-08T06:12:03.000Z'),
      ISODate('2020-02-08T13:13:23.000Z')
    ]
  },
  {
    _id: 1,
    type: 'chocolate',
    orderDate: ISODate('2021-03-20T11:30:05.000Z'),
    state: 'WA',
    price: 14,
    quantity: 140,
    recentOrders: [
      ISODate('2019-01-08T06:12:03.000Z'),
      ISODate('2020-02-08T13:13:23.000Z'),
      ISODate('2021-03-20T11:30:05.000Z')
    ]
  }
]

```

In the example:

- `partitionBy: "$state"` [partitions](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setwindowfields.md#std-label-setWindowFields-partitionBy) the documents in the collection by `state`. There are partitions for `CA` and `WA`.

- `sortBy: { orderDate: 1 }` [sorts](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setwindowfields.md#std-label-setWindowFields-sortBy) the documents in each partition by `orderDate` in ascending order (`1`), so the earliest `orderDate` is first.

- `output`:

  - Sets the `recentOrders` field to an array of `orderDate` values for the documents in each `state`. The array elements are expanded with additions to the previous elements in the array.

  - Uses [`$push`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/push.md#mongodb-group-grp.-push) to return an array of `orderDate` values from the documents in a [range](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setwindowfields.md#std-label-setWindowFields-range) window.

* The [window](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setwindowfields.md#std-label-setWindowFields-window) contains documents between an `unbounded` lower limit and an upper limit set to `10` (10 months after the current document's `orderDate` value) using a time range [unit.](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setwindowfields.md#std-label-setWindowFields-unit)

* [`$push`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/push.md#mongodb-group-grp.-push) returns the array of `orderDate` values for the documents between the beginning of the partition and the documents with `orderDate` values inclusively in a range of the current document's `orderDate` value plus `10` months.

#### Use a Time Range Window with a Negative Upper Bound

The following example uses a [window](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setwindowfields.md#std-label-setWindowFields-window) with a negative upper bound time range [unit](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setwindowfields.md#std-label-setWindowFields-unit) in [`$setWindowFields`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setwindowfields.md#mongodb-pipeline-pipe.-setWindowFields). The pipeline outputs an array of `orderDate` values for each `state` that match the specified time range. In the example output, the `recentOrders` field shows the array of `orderDate` values for `CA` and `WA`.

```javascript
db.cakeSales.aggregate( [
   {
      $setWindowFields: {
         partitionBy: "$state",
         sortBy: { orderDate: 1 },
         output: {
            recentOrders: {
               $push: "$orderDate",
               window: {
                  range: [ "unbounded", -10 ],
                  unit: "month"
               }
            }
         }
      }
   }
] )

```

**Output:**

```javascript
[
  {
    _id: 4,
    type: 'strawberry',
    orderDate: ISODate('2019-05-18T16:09:01.000Z'),
    state: 'CA',
    price: 41,
    quantity: 162,
    recentOrders: []
  },
  {
    _id: 0,
    type: 'chocolate',
    orderDate: ISODate('2020-05-18T14:10:30.000Z'),
    state: 'CA',
    price: 13,
    quantity: 120,
    recentOrders: [
      ISODate('2019-05-18T16:09:01.000Z')
    ]
  },
  {
    _id: 2,
    type: 'vanilla',
    orderDate: ISODate('2021-01-11T06:31:15.000Z'),
    state: 'CA',
    price: 12,
    quantity: 145,
    recentOrders: [
      ISODate('2019-05-18T16:09:01.000Z')
    ]
  },
  {
    _id: 5,
    type: 'strawberry',
    orderDate: ISODate('2019-01-08T06:12:03.000Z'),
    state: 'WA',
    price: 43,
    quantity: 134,
    recentOrders: []
  },
  {
    _id: 3,
    type: 'vanilla',
    orderDate: ISODate('2020-02-08T13:13:23.000Z'),
    state: 'WA',
    price: 13,
    quantity: 104,
    recentOrders: [
      ISODate('2019-01-08T06:12:03.000Z')
    ]
  },
  {
    _id: 1,
    type: 'chocolate',
    orderDate: ISODate('2021-03-20T11:30:05.000Z'),
    state: 'WA',
    price: 14,
    quantity: 140,
    recentOrders: [
      ISODate('2019-01-08T06:12:03.000Z'),
      ISODate('2020-02-08T13:13:23.000Z')
    ]
  }
]

```

In the example:

- `partitionBy: "$state"` [partitions](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setwindowfields.md#std-label-setWindowFields-partitionBy) the documents in the collection by `state`. There are partitions for `CA` and `WA`.

- `sortBy: { orderDate: 1 }` [sorts](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setwindowfields.md#std-label-setWindowFields-sortBy) the documents in each partition by `orderDate` in ascending order (`1`), so the earliest `orderDate` is first.

- `output`:

  - Sets the `recentOrders` field to an array of `orderDate` values for the documents in each `state`. The array elements are expanded with additions to the previous elements in the array.

  - Uses [`$push`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/push.md#mongodb-group-grp.-push) to return an array of `orderDate` values from the documents in a [range](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setwindowfields.md#std-label-setWindowFields-range) window.

* The [window](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setwindowfields.md#std-label-setWindowFields-window) contains documents between an `unbounded` lower limit and an upper limit set to `-10` (10 months before the current document's `orderDate` value) using a time range [unit.](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setwindowfields.md#std-label-setWindowFields-unit)

* [`$push`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/push.md#mongodb-group-grp.-push) returns the array of `orderDate` values for the documents between the beginning of the partition and the documents with `orderDate` values inclusively in a range of the current document's `orderDate` value minus `10` months.

### Comparison with Previous Values Example

The following example uses `$setWindowFields` with the [`$shift`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/shift.md#mongodb-group-grp.-shift) operator and the [`$set`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/set.md#mongodb-pipeline-pipe.-set) stage to compare fields in a collection. In the example output, the `priceComparison` field shows the comparison result.

```javascript
db.cakeSales.aggregate( [
  {
    $setWindowFields: {
      partitionBy: "$type",
      sortBy: { orderDate: 1 },
      output: {
        previousPrice: {
          $shift: {
            output: "$price",
            by: -1
          }
        }
      }
    }
  },
  {
    $set: {
      priceComparison: {
        $cond: [
          { $eq: ["$price", "$previousPrice"] },
          "same",
          {
            $cond: [
              { $gt: ["$price", "$previousPrice"] },
              "higher",
              "lower"
            ]
          }
        ]
      }
    }
  },
] )

```

**Output:**

```javascript
[
  {
    _id: 0,
    type: 'chocolate',
    orderDate: ISODate('2020-05-18T14:10:30.000Z'),
    state: 'CA',
    price: 13,
    quantity: 120,
    previousPrice: null,
    priceComparison: 'higher'
  },
  {
    _id: 1,
    type: 'chocolate',
    orderDate: ISODate('2021-03-20T11:30:05.000Z'),
    state: 'WA',
    price: 14,
    quantity: 140,
    previousPrice: 13,
    priceComparison: 'higher'
  },
  {
    _id: 5,
    type: 'strawberry',
    orderDate: ISODate('2019-01-08T06:12:03.000Z'),
    state: 'WA',
    price: 43,
    quantity: 134,
    previousPrice: null,
    priceComparison: 'higher'
  },
  {
    _id: 4,
    type: 'strawberry',
    orderDate: ISODate('2019-05-18T16:09:01.000Z'),
    state: 'CA',
    price: 41,
    quantity: 162,
    previousPrice: 43,
    priceComparison: 'lower'
  },
  {
    _id: 3,
    type: 'vanilla',
    orderDate: ISODate('2020-02-08T13:13:23.000Z'),
    state: 'WA',
    price: 13,
    quantity: 104,
    previousPrice: null,
    priceComparison: 'higher'
  },
  {
    _id: 2,
    type: 'vanilla',
    orderDate: ISODate('2021-01-11T06:31:15.000Z'),
    state: 'CA',
    price: 12,
    quantity: 145,
    previousPrice: 13,
    priceComparison: 'lower'
  }
]

```

In the example:

- `partitionBy: "$type"` [partitions](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setwindowfields.md#std-label-setWindowFields-partitionBy) the documents in the collection by `type` so each type's calculations are kept separate.

- `sortBy: { orderDate: 1 }` [sorts](https://www.mongodb.com/docs/manual/reference/operator/aggregation/setwindowfields.md#std-label-setWindowFields-sortBy) the documents in each partition by `orderDate` in ascending order (`1`).

- `output.previousPrice` uses the [`$shift`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/shift.md#mongodb-group-grp.-shift) operator to capture the `price` from the immediately preceding order within the same year.

- [`$set`](https://www.mongodb.com/docs/manual/reference/operator/aggregation/set.md#mongodb-pipeline-pipe.-set) adds a new field called `priceComparison`, and sets that field's value to `higher`, `lower`, or `same` based on the comparison to `previousPrice`.

**See also:**

For an additional example about IOT (Internet of Things) Power Consumption, see the [Practical MongoDB Aggregations](https://www.practical-mongodb-aggregations.com/examples/time-series/iot-power-consumption.html) e-book.
