Definition定义
$setWindowFields
New in version 5.0.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.对集合(称为窗口)中指定范围的文档执行操作,并根据所选的窗口运算符返回结果。
For example, you can use the 例如,您可以使用$setWindowFields
stage to output the:$setWindowFields
阶段输出:
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
stage syntax:$setWindowFields
阶段语法:
{
$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
stage takes a document with these fields:
partitionBy | Optional | Specifies an expression to group the documents. In the |
sortBy | Required for some operators (see Restrictions) | Specifies the field(s) to sort the documents by in the partition. Uses the same syntax as the |
output | Required | Specifies the field(s) to append to the documents in the output returned by the A field can contain dots to specify embedded document fields and array fields. The semantics for the embedded document dotted notation in the
|
window | Optional | Specifies the window boundaries and parameters. Window boundaries are inclusive. Default is an unbounded window, which includes all documents in the partition. |
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:
|
range | Optional | A window where the lower and upper boundaries are defined using a range of values based on the sortBy field in the current document.
|
unit | Optional | Specifies the units for time range window boundaries. Can be set to one of these strings:
If omitted, default numeric range window boundaries are used. |
Tip
Behavior行为
The $setWindowFields
stage appends new fields to existing documents. You can include one or more $setWindowFields
stages in an aggregation operation.
Starting in MongoDB 5.3, you can use the $setWindowFields
stage with transactions and the "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
stage:
- Accumulator operators:
$addToSet
,$avg
,$bottom
,$bottomN
,$concatArrays
,$count
,$covariancePop
,$covarianceSamp
,$derivative
,$expMovingAvg
,$firstN
,$integral
,$lastN
,$max
,$maxN
,$median
,$min
,$minN
,$percentile
,$push
,$setUnion
,$stdDevSamp
,$stdDevPop
,$sum
,$top
,$topN
.
- Gap filling operators:
$linearFill
and$locf
.
- Rank operators:
$denseRank
,$documentNumber
, and$rank
. - Range operator:
$minMaxScaler
Restrictions
Restrictions for the $setWindowFields
stage:
- Prior to MongoDB 5.3, the
$setWindowFields
stage cannot be used:- Within transactions.
- With
"snapshot"
read concern.
- sortBy is required for:
- Rank and order window operators.
- Bounded windows (either a documents window or a range window).
$linearFill
operator.
- 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.
- You cannot specify both a documents window and a range window.
- These operators use an implicit window and return an error if you specify a window option:
- 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 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
on strings), the returned value depends on the operator:
Examples
Create a cakeSales
collection that contains cake sales in the states of California (CA
) and Washington (WA
):
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 window in $setWindowFields
to output the cumulative cake sales quantity
for each state
:
db.cakeSales.aggregate( [
{
$setWindowFields: {
partitionBy: "$state",
sortBy: { orderDate: 1 },
output: {
cumulativeQuantityForState: {
$sum: "$quantity",
window: {
documents: [ "unbounded", "current" ]
}
}
}
}
}
] )
In the example:
partitionBy: "$state"
partitions the documents in the collection bystate
. There are partitions forCA
andWA
.sortBy: { orderDate: 1 }
sorts the documents in each partition byorderDate
in ascending order (1
), so the earliestorderDate
is first.
output
:- Sets the
cumulativeQuantityForState
field to the cumulativequantity
for eachstate
, which increases by successive additions to the previous value in the partition. - Calculates the cumulative
quantity
using the$sum
operator run in a documents window.
The window contains documents between anunbounded
lower limit and thecurrent
document. This means$sum
returns the cumulativequantity
for the documents between the beginning of the partition and the current document.
- Sets the
In this example output, the cumulative quantity
for CA
and WA
is shown in the cumulativeQuantityForState
field:
{ "_id" : 4, "type" : "strawberry", "orderDate" : ISODate("2019-05-18T16:09:01Z"),
"state" : "CA", "price" : 41, "quantity" : 162, "cumulativeQuantityForState" : 162 }
{ "_id" : 0, "type" : "chocolate", "orderDate" : ISODate("2020-05-18T14:10:30Z"),
"state" : "CA", "price" : 13, "quantity" : 120, "cumulativeQuantityForState" : 282 }
{ "_id" : 2, "type" : "vanilla", "orderDate" : ISODate("2021-01-11T06:31:15Z"),
"state" : "CA", "price" : 12, "quantity" : 145, "cumulativeQuantityForState" : 427 }
{ "_id" : 5, "type" : "strawberry", "orderDate" : ISODate("2019-01-08T06:12:03Z"),
"state" : "WA", "price" : 43, "quantity" : 134, "cumulativeQuantityForState" : 134 }
{ "_id" : 3, "type" : "vanilla", "orderDate" : ISODate("2020-02-08T13:13:23Z"),
"state" : "WA", "price" : 13, "quantity" : 104, "cumulativeQuantityForState" : 238 }
{ "_id" : 1, "type" : "chocolate", "orderDate" : ISODate("2021-03-20T11:30:05Z"),
"state" : "WA", "price" : 14, "quantity" : 140, "cumulativeQuantityForState" : 378 }
Use Documents Window to Obtain Cumulative Quantity for Each Year
This example uses a documents window in $setWindowFields
to output the cumulative cake sales quantity
for each $year
in orderDate
:
db.cakeSales.aggregate( [
{
$setWindowFields: {
partitionBy: { $year: "$orderDate" },
sortBy: { orderDate: 1 },
output: {
cumulativeQuantityForYear: {
$sum: "$quantity",
window: {
documents: [ "unbounded", "current" ]
}
}
}
}
}
] )
In the example:
partitionBy: { $year: "$orderDate" }
partitions the documents in the collection by$year
inorderDate
. There are are partitions for2019
,2020
, and2021
.sortBy: { orderDate: 1 }
sorts the documents in each partition byorderDate
in ascending order (1
), so the earliestorderDate
is first.output
:- Sets the
cumulativeQuantityForYear
field to the cumulativequantity
for each year, which increases by successive additions to the previous value in the partition. - Calculates the cumulative
quantity
using the$sum
operator run in a documents window.
The window contains documents between anunbounded
lower limit and thecurrent
document. This means$sum
returns the cumulativequantity
for the documents between the beginning of the partition and the current document.
- Sets the
In this example output, the cumulative quantity
for each year is shown in the cumulativeQuantityForYear
field:
{ "_id" : 5, "type" : "strawberry", "orderDate" : ISODate("2019-01-08T06:12:03Z"),
"state" : "WA", "price" : 43, "quantity" : 134, "cumulativeQuantityForYear" : 134 }
{ "_id" : 4, "type" : "strawberry", "orderDate" : ISODate("2019-05-18T16:09:01Z"),
"state" : "CA", "price" : 41, "quantity" : 162, "cumulativeQuantityForYear" : 296 }
{ "_id" : 3, "type" : "vanilla", "orderDate" : ISODate("2020-02-08T13:13:23Z"),
"state" : "WA", "price" : 13, "quantity" : 104, "cumulativeQuantityForYear" : 104 }
{ "_id" : 0, "type" : "chocolate", "orderDate" : ISODate("2020-05-18T14:10:30Z"),
"state" : "CA", "price" : 13, "quantity" : 120, "cumulativeQuantityForYear" : 224 }
{ "_id" : 2, "type" : "vanilla", "orderDate" : ISODate("2021-01-11T06:31:15Z"),
"state" : "CA", "price" : 12, "quantity" : 145, "cumulativeQuantityForYear" : 145 }
{ "_id" : 1, "type" : "chocolate", "orderDate" : ISODate("2021-03-20T11:30:05Z"),
"state" : "WA", "price" : 14, "quantity" : 140, "cumulativeQuantityForYear" : 285 }
Use Documents Window to Obtain Moving Average Quantity for Each Year
This example uses a documents window in $setWindowFields
to output the moving average for the cake sales quantity
:
db.cakeSales.aggregate( [
{
$setWindowFields: {
partitionBy: { $year: "$orderDate" },
sortBy: { orderDate: 1 },
output: {
averageQuantity: {
$avg: "$quantity",
window: {
documents: [ -1, 0 ]
}
}
}
}
}
] )
In the example:
partitionBy: "$orderDate"
partitions the documents in the collection by$year
inorderDate
. There are are partitions for2019
,2020
, and2021
.sortBy: { orderDate: 1 }
sorts the documents in each partition byorderDate
in ascending order (1
), so the earliestorderDate
is first.output
:- Sets the
averageQuantity
field to the moving averagequantity
for each year. - Calculates the moving average
quantity
using the$avg
operator run in a documents window.
The window contains documents between-1
and0
. This means$avg
returns the moving averagequantity
between the document before the current document (-1
) and the current document (0
) in the partition.
- Sets the
In this example output, the moving average quantity
is shown in the averageQuantity
field:
{ "_id" : 5, "type" : "strawberry", "orderDate" : ISODate("2019-01-08T06:12:03Z"),
"state" : "WA", "price" : 43, "quantity" : 134, "averageQuantity" : 134 }
{ "_id" : 4, "type" : "strawberry", "orderDate" : ISODate("2019-05-18T16:09:01Z"),
"state" : "CA", "price" : 41, "quantity" : 162, "averageQuantity" : 148 }
{ "_id" : 3, "type" : "vanilla", "orderDate" : ISODate("2020-02-08T13:13:23Z"),
"state" : "WA", "price" : 13, "quantity" : 104, "averageQuantity" : 104 }
{ "_id" : 0, "type" : "chocolate", "orderDate" : ISODate("2020-05-18T14:10:30Z"),
"state" : "CA", "price" : 13, "quantity" : 120, "averageQuantity" : 112 }
{ "_id" : 2, "type" : "vanilla", "orderDate" : ISODate("2021-01-11T06:31:15Z"),
"state" : "CA", "price" : 12, "quantity" : 145, "averageQuantity" : 145 }
{ "_id" : 1, "type" : "chocolate", "orderDate" : ISODate("2021-03-20T11:30:05Z"),
"state" : "WA", "price" : 14, "quantity" : 140, "averageQuantity" : 142.5 }
Use Documents Window to Obtain Cumulative and Maximum Quantity for Each Year
This example uses a documents window in $setWindowFields
to output the cumulative and maximum cake sales quantity
values for each $year
in orderDate
:
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" ]
}
}
}
}
}
] )
In the example:
partitionBy: "$orderDate"
partitions the documents in the collection by$year
inorderDate
. There are are partitions for2019
,2020
, and2021
.sortBy: { orderDate: 1 }
sorts the documents in each partition byorderDate
in ascending order (1
), so the earliestorderDate
is first.output
:- Sets the
cumulativeQuantityForYear
field to the cumulativequantity
for each year. - Calculates the cumulative
quantity
using the$sum
operator run in a documents window.The window contains documents between an
unbounded
lower limit and thecurrent
document. This means$sum
returns the cumulative quantity for the documents between the beginning of the partition and the current document. - Sets the
maximumQuantityForYear
field to the maximumquantity
for each year. - Calculates the maximum
quantity
of all the documents using the$max
operator run in a documents window.
The window contains documents between anunbounded
lower andupper
limit. This means$max
returns the maximum quantity for the documents in the partition.
- Sets the
In this example output, the cumulative quantity
is shown in the cumulativeQuantityForYear
field and the maximum quantity
is shown in the maximumQuantityForYear
field:
{ "_id" : 5, "type" : "strawberry", "orderDate" : ISODate("2019-01-08T06:12:03Z"),
"state" : "WA", "price" : 43, "quantity" : 134,
"cumulativeQuantityForYear" : 134, "maximumQuantityForYear" : 162 }
{ "_id" : 4, "type" : "strawberry", "orderDate" : ISODate("2019-05-18T16:09:01Z"),
"state" : "CA", "price" : 41, "quantity" : 162,
"cumulativeQuantityForYear" : 296, "maximumQuantityForYear" : 162 }
{ "_id" : 3, "type" : "vanilla", "orderDate" : ISODate("2020-02-08T13:13:23Z"),
"state" : "WA", "price" : 13, "quantity" : 104,
"cumulativeQuantityForYear" : 104, "maximumQuantityForYear" : 120 }
{ "_id" : 0, "type" : "chocolate", "orderDate" : ISODate("2020-05-18T14:10:30Z"),
"state" : "CA", "price" : 13, "quantity" : 120,
"cumulativeQuantityForYear" : 224, "maximumQuantityForYear" : 120 }
{ "_id" : 2, "type" : "vanilla", "orderDate" : ISODate("2021-01-11T06:31:15Z"),
"state" : "CA", "price" : 12, "quantity" : 145,
"cumulativeQuantityForYear" : 145, "maximumQuantityForYear" : 145 }
{ "_id" : 1, "type" : "chocolate", "orderDate" : ISODate("2021-03-20T11:30:05Z"),
"state" : "WA", "price" : 14, "quantity" : 140,
"cumulativeQuantityForYear" : 285, "maximumQuantityForYear" : 145 }
Range Window Example
This example uses a range window in $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:
db.cakeSales.aggregate( [
{
$setWindowFields: {
partitionBy: "$state",
sortBy: { price: 1 },
output: {
quantityFromSimilarOrders: {
$sum: "$quantity",
window: {
range: [ -10, 10 ]
}
}
}
}
}
] )
In the example:
partitionBy: "$state"
partitions the documents in the collection bystate
. There are partitions forCA
andWA
.sortBy: { price: 1 }
sorts the documents in each partition byprice
in ascending order (1
), so the lowestprice
is first.output
sets thequantityFromSimilarOrders
field to the sum of thequantity
values from the documents in a range window.
In this example output, the sum of the quantity
values for documents in the window is shown in the quantityFromSimilarOrders
field:
{ "_id" : 2, "type" : "vanilla", "orderDate" : ISODate("2021-01-11T06:31:15Z"),
"state" : "CA", "price" : 12, "quantity" : 145, "quantityFromSimilarOrders" : 265 }
{ "_id" : 0, "type" : "chocolate", "orderDate" : ISODate("2020-05-18T14:10:30Z"),
"state" : "CA", "price" : 13, "quantity" : 120, "quantityFromSimilarOrders" : 265 }
{ "_id" : 4, "type" : "strawberry", "orderDate" : ISODate("2019-05-18T16:09:01Z"),
"state" : "CA", "price" : 41, "quantity" : 162, "quantityFromSimilarOrders" : 162 }
{ "_id" : 3, "type" : "vanilla", "orderDate" : ISODate("2020-02-08T13:13:23Z"),
"state" : "WA", "price" : 13, "quantity" : 104, "quantityFromSimilarOrders" : 244 }
{ "_id" : 1, "type" : "chocolate", "orderDate" : ISODate("2021-03-20T11:30:05Z"),
"state" : "WA", "price" : 14, "quantity" : 140, "quantityFromSimilarOrders" : 244 }
{ "_id" : 5, "type" : "strawberry", "orderDate" : ISODate("2019-01-08T06:12:03Z"),
"state" : "WA", "price" : 43, "quantity" : 134, "quantityFromSimilarOrders" : 134 }
Time Range Window Examples
Use a Time Range Window with a Positive Upper Bound
The following example uses a window with a positive upper bound time range unit in $setWindowFields
. The pipeline outputs an array of orderDate
values for each state
that match the specified time range.
db.cakeSales.aggregate( [
{
$setWindowFields: {
partitionBy: "$state",
sortBy: { orderDate: 1 },
output: {
recentOrders: {
$push: "$orderDate",
window: {
range: [ "unbounded", 10 ],
unit: "month"
}
}
}
}
}
] )
In the example:
partitionBy: "$state"
partitions the documents in the collection bystate
. There are partitions forCA
andWA
.sortBy: { orderDate: 1 }
sorts the documents in each partition byorderDate
in ascending order (1
), so the earliestorderDate
is first.output
:
- The window contains documents between an
unbounded
lower limit and an upper limit set to10
(10 months after the current document'sorderDate
value) using a time range unit. $push
returns the array oforderDate
values for the documents between the beginning of the partition and the documents withorderDate
values inclusively in a range of the current document'sorderDate
value plus10
months.
In this example output, the array of orderDate
values for CA
and WA
is shown in the recentOrders
field:
{ "_id" : 4, "type" : "strawberry", "orderDate" : ISODate("2019-05-18T16:09:01Z"),
"state" : "CA", "price" : 41, "quantity" : 162,
"recentOrders" : [ ISODate("2019-05-18T16:09:01Z") ] }
{ "_id" : 0, "type" : "chocolate", "orderDate" : ISODate("2020-05-18T14:10:30Z"),
"state" : "CA", "price" : 13, "quantity" : 120,
"recentOrders" : [ ISODate("2019-05-18T16:09:01Z"), ISODate("2020-05-18T14:10:30Z"), ISODate("2021-01-11T06:31:15Z") ] }
{ "_id" : 2, "type" : "vanilla", "orderDate" : ISODate("2021-01-11T06:31:15Z"),
"state" : "CA", "price" : 12, "quantity" : 145,
"recentOrders" : [ ISODate("2019-05-18T16:09:01Z"), ISODate("2020-05-18T14:10:30Z"), ISODate("2021-01-11T06:31:15Z") ] }
{ "_id" : 5, "type" : "strawberry", "orderDate" : ISODate("2019-01-08T06:12:03Z"),
"state" : "WA", "price" : 43, "quantity" : 134,
"recentOrders" : [ ISODate("2019-01-08T06:12:03Z") ] }
{ "_id" : 3, "type" : "vanilla", "orderDate" : ISODate("2020-02-08T13:13:23Z"),
"state" : "WA", "price" : 13, "quantity" : 104,
"recentOrders" : [ ISODate("2019-01-08T06:12:03Z"), ISODate("2020-02-08T13:13:23Z") ] }
{ "_id" : 1, "type" : "chocolate", "orderDate" : ISODate("2021-03-20T11:30:05Z"),
"state" : "WA", "price" : 14, "quantity" : 140,
"recentOrders" : [ ISODate("2019-01-08T06:12:03Z"), ISODate("2020-02-08T13:13:23Z"), ISODate("2021-03-20T11:30:05Z") ] }
Use a Time Range Window with a Negative Upper Bound
The following example uses a window with a negative upper bound time range unit in $setWindowFields
. The pipeline outputs an array of orderDate
values for each state
that match the specified time range.
db.cakeSales.aggregate( [
{
$setWindowFields: {
partitionBy: "$state",
sortBy: { orderDate: 1 },
output: {
recentOrders: {
$push: "$orderDate",
window: {
range: [ "unbounded", -10 ],
unit: "month"
}
}
}
}
}
] )
In the example:
partitionBy: "$state"
partitions the documents in the collection bystate
. There are partitions forCA
andWA
.sortBy: { orderDate: 1 }
sorts the documents in each partition byorderDate
in ascending order (1
), so the earliestorderDate
is first.output
:
- The window contains documents between an
unbounded
lower limit and an upper limit set to-10
(10 months before the current document'sorderDate
value) using a time range unit. $push
returns the array oforderDate
values for the documents between the beginning of the partition and the documents withorderDate
values inclusively in a range of the current document'sorderDate
value minus10
months.
In this example output, the array of orderDate
values for CA
and WA
is shown in the recentOrders
field:
{ "_id" : 4, "type" : "strawberry", "orderDate" : ISODate("2019-05-18T16:09:01Z"),
"state" : "CA", "price" : 41, "quantity" : 162,
"recentOrders" : [ ] }
{ "_id" : 0, "type" : "chocolate", "orderDate" : ISODate("2020-05-18T14:10:30Z"),
"state" : "CA", "price" : 13, "quantity" : 120,
"recentOrders" : [ ISODate("2019-05-18T16:09:01Z") ] }
{ "_id" : 2, "type" : "vanilla", "orderDate" : ISODate("2021-01-11T06:31:15Z"),
"state" : "CA", "price" : 12, "quantity" : 145,
"recentOrders" : [ ISODate("2019-05-18T16:09:01Z") ] }
{ "_id" : 5, "type" : "strawberry", "orderDate" : ISODate("2019-01-08T06:12:03Z"),
"state" : "WA", "price" : 43, "quantity" : 134,
"recentOrders" : [ ] }
{ "_id" : 3, "type" : "vanilla", "orderDate" : ISODate("2020-02-08T13:13:23Z"),
"state" : "WA", "price" : 13, "quantity" : 104,
"recentOrders" : [ ISODate("2019-01-08T06:12:03Z") ] }
{ "_id" : 1, "type" : "chocolate", "orderDate" : ISODate("2021-03-20T11:30:05Z"),
"state" : "WA", "price" : 14, "quantity" : 140,
"recentOrders" : [ ISODate("2019-01-08T06:12:03Z"), ISODate("2020-02-08T13:13:23Z") ] }
Comparison with Previous Values Example
The following example uses $setWindowFields
with the $shift
operator and the $set
stage to compare fields in a collection.
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"
]
}
]
}
}
},
] )
In the example:
partitionBy: "$type"
partitions the documents in the collection bytype
so each type's calculations are kept separate.sortBy: { orderDate: 1 }
sorts the documents in each partition byorderDate
in ascending order (1
).output.previousPrice
uses the$shift
operator to capture theprice
from the immediately preceding order within the same year.$set
adds a new field calledpriceComparison
, and sets that field's value tohigher
,lower
, orsame
based on the comparison topreviousPrice
.
In this example output, the comparison result is shown in the priceComparison
field:
[
{
_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'
}
]
The following WeatherMeasurement
class represents documents in a collection of weather measurements:
public class WeatherMeasurement
{
public Guid Id { get; set; }
public string LocalityId { get; set; }
public DateTime MeasurementDateTime { get; set; }
public float Rainfall { get; set; }
public float Temperature { get; set; }
}
To use the MongoDB .NET/C# driver to add a $setWindowFields
stage to an aggregation pipeline, call the SetWindowFields()
method on a PipelineDefinition
object.
The following example creates a pipeline stage that uses the Rainfall
and Temperature
fields to compute the accumulated rainfall and a moving average temperature over the past month for each locality:
var pipeline = new EmptyPipelineDefinition<WeatherMeasurement>()
.SetWindowFields(
partitionBy: w => w.LocalityId,
sortBy: Builders<WeatherMeasurement>.Sort.Ascending(
w => w.MeasurementDateTime),
output: o => new
{
MonthlyRainfall = o.Sum(
w => w.Rainfall, RangeWindow.Create(
RangeWindow.Months(-1),
RangeWindow.Current)
),
TemperatureAvg = o.Average(
w => w.Temperature, RangeWindow.Create(
RangeWindow.Months(-1),
RangeWindow.Current)
)
}
);
The Node.js examples on this page use the sample_weatherdata.data
collection from the Atlas sample datasets. To learn how to create a free MongoDB Atlas cluster and load the sample datasets, see Get Started in the MongoDB Node.js driver documentation.
To use the MongoDB Node.js driver to add a $setWindowFields
stage to an aggregation pipeline, use the $setWindowFields
operator in a pipeline object.
The following example creates a pipeline stage that calculates the average airTemperature.value
and the total waveMeasurement.waves.height
for each unique value of callLetters
over the past month. The example then runs the aggregation pipeline:
const pipeline = [
{
$setWindowFields: {
partitionBy: "$callLetters",
sortBy: { ts: 1 },
output: {
temperatureAvg: {
$avg: "$airTemperature.value",
window: {
range: [-1, "current"],
unit: "month"
}
},
totalWaveHeight: {
$sum: "$waveMeasurement.waves.height",
window: {
range: [-1, "current"],
unit: "month"
}
}
}
}
},
];
const cursor = collection.aggregate(pipeline);
return cursor;
Tip
For an additional example about IOT Power Consumption, see the Practical MongoDB Aggregations e-book.