$setWindowFields (aggregation)

On this page本页内容

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:$setWindowFields阶段接收包含以下字段的文档:

Field字段Necessity必要性Description描述
partitionByOptional可选

Specifies an expression to group the documents. 指定用于对文档进行分组的表达式In the $setWindowFields stage, the group of documents is known as a partition. $setWindowFields阶段,文档组称为“分区”。Default is one partition for the entire collection.默认为整个集合的一个分区。

sortByRequired for some operators (see Restrictions)某些运算符需要(参见限制

Specifies the field(s) to sort the documents by in the partition. 指定分区中文档排序依据的字段。Uses the same syntax as the $sort stage. 使用与$sort阶段相同的语法。Default is no sorting.默认情况下不进行排序。

outputRequired必要

Specifies the field(s) to append to the documents in the output returned by the $setWindowFields stage. 指定要附加到$setWindowFields阶段返回的输出中的文档的字段。Each field is set to the result returned by the window operator.每个字段都设置为窗口运算符返回的结果。

A field can contain dots to specify embedded document fields and array fields. 字段可以包含,以指定嵌入的文档字段和数组字段。The semantics for the embedded document dotted notation in the $setWindowFields stage are the same as the $addFields and $set stages. $setWindowFields阶段中嵌入的文档点符号的语义与$addFields和$set阶段相同。See embedded document $addFields example and embedded document $set example.请参见嵌入式文档$addFields示例嵌入式文档$set示例

windowOptional可选

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 or range window.指定文档窗口或范围窗口。

documentsOptional可选

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.输出中当前文档位置的"current"字符串。
  • The "unbounded" string for the first or last document position in the partition.分区中第一个或最后一个文档位置的"unbounded"字符串。
  • 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.0是当前文档位置。

See Documents Window Examples.请参阅文档窗口示例

rangeOptional可选

A window where the lower and upper boundaries are defined using a range of values based on the sortBy field in the current document.使用基于当前文档中sortBy字段的一系列值定义上下限的窗口。

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.输出中当前文档位置的"current"字符串。
  • The "unbounded" string for the first or last document position in the partition.分区中第一个或最后一个文档位置的"unbounded"字符串。
  • A number to add to the value of the sortBy field for the current document. 要添加到当前文档的sortBy字段值中的数字。A document is in the window if the sortBy field value is inclusively within the lower and upper boundaries.如果sortBy字段值包含在上下边界内,则文档将显示在窗口中。

See Range Window Example.请参阅范围窗口示例

unitOptional可选

Specifies the units for time 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 window boundaries are used.如果省略,则使用默认的数值范围窗口边界。

See Time Range Window Examples.请参阅时间范围窗口示例

Tip提示
See also: 另请参阅:

Behavior行为

The $setWindowFields stage appends new fields to existing documents. $setWindowFields阶段将新字段附加到现有文档中。You can include one or more $setWindowFields stages in an aggregation operation.可以在聚合操作中包含一个或多个$setWindowFields阶段。

Starting in MongoDB 5.3, you can use the $setWindowFields stage with transactions and the "snapshot" read concern.从MongoDB 5.3开始,您可以使用$setWindowFields阶段处理事务"snapshot"读取问题。

Window Operators窗口运算符

These operators can be used with the $setWindowFields stage:这些运算符可用于$setWindowFields阶段:

Restrictions限制

Restrictions for the $setWindowFields stage:$setWindowFields阶段的限制:

  • Starting in MongoDB 5.1 (and 5.0.4), the $setWindowFields stage cannot be used:从MongoDB 5.1(和5.0.4)开始,$setWindowFields阶段不能在以下情况中使用:

  • sortBy is required for:对以下情况必不可少:

  • Range windows require all sortBy values to be numbers.范围窗口要求所有sortBy值都是数字。
  • Time range windows require all sortBy values to be dates.时间范围窗口要求所有sortBy值都是日期。
  • Range and time range windows can only contain one sortBy field and the sort must be ascending.范围窗口和时间范围窗口只能包含一个sortBy字段,排序必须是升序。
  • 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:如果指定window选项,这些运算符将使用隐式窗口并返回错误:

  • For range windows, only numbers in the specified range are included in the window. 对于范围窗口,窗口中只包含指定范围内的数字。Missing, undefined, and null values are excluded.排除缺失、未定义和null值。
  • 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.数值边界值必须是整数。例如,可以使用2小时作为边界,但不能使用1.5小时。
  • For empty windows or windows with incompatible values (for example, using $sum on strings), the returned value depends on the operator:对于空窗口或具有不兼容值的窗口(例如,在字符串上使用$sum),返回值取决于运算符:

    • For $count and $sum, the returned value is 0.对于$count$sum,返回值为0
    • For $addToSet and $push, the returned value is an empty array.对于$addToSet$push,返回的值是一个空数组。
    • For all other operators, the returned value is null.对于所有其他运算符,返回值均为null

Examples示例

Create a cakeSales collection that contains cake sales in the states of California (CA) and Washington (WA):创建cakeSales集合,包含加利福尼亚州(CA)和华盛顿州(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.以下示例使用cakeSales集合。

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:本例使用$setWindowFields中的文档窗口输出每个州的累积蛋糕销售数量:

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 by state. 按州对集合中的文档进行分区There are partitions for CA and WA.CAWA有分区。
  • sortBy: { orderDate: 1 } sorts the documents in each partition by orderDate in ascending order (1), so the earliest orderDate is first.orderDate按升序(1)对每个分区中的文档进行排序,因此最早的orderDate是第一个。
  • output:

    • Sets the cumulativeQuantityForState field to the cumulative quantity for each state, which increases by successive additions to the previous value in the partition.cumulativeQuantityForState字段设置为每个州的累积数量,该数量通过连续添加到分区中的前一个值来增加。
    • Calculates the cumulative quantity using the $sum operator run in a documents window.使用文档窗口中运行的$sum运算符计算累计数量。

      The window contains documents between an unbounded lower limit and the current document. 窗口包含的文档介于unbounded下限和current文档之间。This means $sum returns the cumulative quantity for the documents between the beginning of the partition and the current document.这意味着$sum返回分区开始和当前文档之间的文档累积数量。

In this example output, the cumulative quantity for CA and WA is shown in the cumulativeQuantityForState field:在此示例输出中,CAWA的累积数量显示在cumulativeQuantityForState字段中:

{ "_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:本例使用$setWindowFields中的文档窗口输出orderDate中每个$year的累积蛋糕销售数量:

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

In the example:在示例中:

  • partitionBy: "$state" partitions the documents in the collection by $year in orderDate. orderDate中的$year对集合中的文档进行分区There are are partitions for 2019, 2020, and 2021.201920202021三个分区。
  • sortBy: { orderDate: 1 } sorts the documents in each partition by orderDate in ascending order (1), so the earliest orderDate is first.orderDate按升序(1)对每个分区中的文档进行排序,因此最早的orderDate是第一个。
  • output:

    • Sets the cumulativeQuantityForYear field to the cumulative quantity for each year, which increases by successive additions to the previous value in the partition.cumulativeQuantityForYear字段设置为每年的累计数量,该数量通过连续添加到分区中的上一个值来增加。
    • Calculates the cumulative quantity using the $sum operator run in a documents window.使用文档窗口中运行的$sum运算符计算累计数量。

      The window contains documents between an unbounded lower limit and the current document. 窗口包含的文档介于unbounded下限和current文档之间。This means $sum returns the cumulative quantity for the documents between the beginning of the partition and the current document.这意味着$sum返回分区开始和当前文档之间的文档累积数量。

In this example output, the cumulative quantity for each year is shown in the cumulativeQuantityForYear field:在本例输出中,每年的累计数量显示在cumulativeQuantityForYear字段中:

{ "_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:本例使用$setWindowFields中的文档窗口输出蛋糕销售数量的移动平均值:

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 in orderDate. orderDate中的$year对集合中的文档进行分区There are are partitions for 2019, 2020, and 2021.201920202021三个分区。
  • sortBy: { orderDate: 1 } sorts the documents in each partition by orderDate in ascending order (1), so the earliest orderDate is first.orderDate按升序(1)对每个分区中的文档进行排序,因此最早的orderDate是第一个。
  • output:

    • Sets the averageQuantity field to the moving average quantity for each year.averageQuantity字段设置为每年的移动平均数量。
    • Calculates the moving average quantity using the $avg operator run in a documents window.使用在文档窗口中运行的$avg运算符计算移动平均数量。

      The window contains documents between -1 and 0. 窗口包含介于-10之间的文档。This means $avg returns the moving average quantity between the document before the current document (-1) and the current document (0) in the partition.这意味着$avg返回分区中当前文档(-1)之前的文档和当前文档(0)之间的移动平均数量。

In this example output, the moving average quantity is shown in the averageQuantity field:在此示例输出中,移动平均数量显示在averageQuantity字段中:

{ "_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:本例使用$setWindowFields中的文档窗口输出orderDate中每个$year的累积蛋糕销售数量值和最大蛋糕销售数量值:

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 in orderDate. orderDate中的$year对集合中的文档进行分区There are are partitions for 2019, 2020, and 2021.201920202021三个分区。
  • sortBy: { orderDate: 1 } sorts the documents in each partition by orderDate in ascending order (1), so the earliest orderDate is first.orderDate按升序(1)对每个分区中的文档进行排序,因此最早的orderDate是第一个。
  • output:

    • Sets the cumulativeQuantityForYear field to the cumulative quantity for each year.cumulativeQuantityForYear字段设置为每年的累积数量。
    • Calculates the cumulative quantity using the $sum operator run in a documents window.使用文档窗口中运行的$sum运算符计算累计数量。

      The window contains documents between an unbounded lower limit and the current document. 窗口包含的文档介于unbounded下限和current文档之间。This means $sum returns the cumulative quantity for the documents between the beginning of the partition and the current document.这意味着$sum返回分区开始和当前文档之间的文档累积数量。

    • Sets the maximumQuantityForYear field to the maximum quantity for each year.maximumQuantityForYear字段设置为每年的最大数量。
    • Calculates the maximum quantity of all the documents using the $max operator run in a documents window.使用文档窗口中运行的$max运算符计算所有文档的最大数量。

      The window contains documents between an unbounded lower and upper limit. 窗口包含的文档介于unbounded上限和unbounded下限之间。This means $max returns the maximum quantity for the documents in the partition.这意味着$max返回分区中文档的最大数量。

In this example output, the cumulative quantity is shown in the cumulativeQuantityForYear field and the maximum quantity is shown in the maximumQuantityForYear field:在此示例输出中,累积数量显示在cumulativeQuantityForYear字段中,最大数量显示在maximumQuantityForYear字段中:

{ "_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:本例使用$setWindowFields中的一个范围窗口,返回当前文档价格正负10美元范围内的订单销售蛋糕数量值之和:

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 by state. 按州对集合中的文档进行分区There are partitions for CA and WA.CAWA有分区。
  • sortBy: { price: 1 } sorts the documents in each partition by price in ascending order (1), so the lowest price is first.price升序(1)对每个分区中的文档进行排序,因此最低price为第一。
  • output sets the quantityFromSimilarOrders field to the sum of the quantity values from the documents in a range window.quantityFromSimilarOrders字段设置为范围窗口中文档的数量值之和。

    • The window contains documents between a lower limit of -10 and an upper limit of 10. 窗口包含下限为-10和上限为10之间的文档。The range is inclusive.范围包括-1010
    • $sum returns the sum of quantity values contained in a range of plus or minus 10 dollars of the current document's price value.$sum返回当前文档price的正负10美元范围内的数量值之和。

In this example output, the sum of the quantity values for documents in the window is shown in the quantityFromSimilarOrders field:在此示例输出中,窗口中文档的数量值之和显示在quantityFromSimilarOrders字段中:

{ "_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. 以下示例使用了一个以$setWindowFields为单位的时间范围上限为正的窗口The pipeline outputs an array of orderDate values for each state that match the specified time range.管道输出与指定时间范围匹配的每个州的orderDate值数组。

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 by state. 按州对集合中的文档进行分区There are partitions for CA and WA.CAWA有分区。
  • sortBy: { orderDate: 1 } sorts the documents in each partition by orderDate in ascending order (1), so the earliest orderDate is first.orderDate按升序(1)对每个分区中的文档进行排序,因此最早的orderDate是第一个。
  • output:

    • Sets the orderDateArrayForState array field to orderDate values for the documents in each state. orderDateArrayForState数组字段设置为每个州下文档的orderDate值。The array elements are expanded with additions to the previous elements in the array.数组元素通过添加到数组中以前的元素来展开。
    • Uses $push to return an array of orderDate values from the documents in a range window.使用$push范围窗口中的文档返回orderDate值数组。
  • The 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.窗口包含使用时间范围单位设置为10(当前文档的orderDate值后10个月)的unbounded下限和unbounded上限之间的文档。
  • $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.返回分区开头和orderDate值在当前文档的orderDate值加上10个月范围内的文档之间的orderDate值数组。

In this example output, the array of orderDate values for CA and WA is shown in the recentOrders field:在此示例输出中,CAWAorderDate值数组显示在recentOrders字段中:

{ "_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. 以下示例使用了一个时间范围单位为负的窗口,单位为$setWindowFieldsThe pipeline outputs an array of orderDate values for each state that match the specified time range.管道输出与指定时间范围匹配的每个州的orderDate值数组。

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 by state. 按州对集合中的文档进行分区There are partitions for CA and WA.CAWA有分区。
  • sortBy: { orderDate: 1 } sorts the documents in each partition by orderDate in ascending order (1), so the earliest orderDate is first.orderDate按升序(1)对每个分区中的文档进行排序,因此最早的orderDate是第一个。
  • output:

    • Sets the orderDateArrayForState array field to orderDate values for the documents in each state. orderDateArrayForState数组字段设置为每个州下文档的orderDate值。The array elements are expanded with additions to the previous elements in the array.数组元素通过添加到数组中以前的元素来展开。
    • Uses $push to return an array of orderDate values from the documents in a range window.使用$push范围窗口中的文档返回orderDate值数组。
  • The 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.窗口包含使用时间范围单位设置为-10(当前文档的orderDate值前10个月)的unbounded下限和unbounded上限之间的文档。
  • $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.$push返回分区开头和orderDate值在当前文档的orderDate值减去10个月范围内的文档之间的orderDate值数组。

In this example output, the array of orderDate values for CA and WA is shown in the recentOrders field:在此示例输出中,CAWAorderDate值数组显示在recentOrders字段中:

{ "_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") ] }
Tip提示
See also: 另请参阅:

For an additional example about IOT Power Consumption, see the Practical MongoDB Aggregations e-book.有关物联网功耗的其他示例,请参阅《实用MongoDB聚合》电子书。

←  $set (aggregation)$skip (aggregation) →