Docs Menu
Docs Home
/ /

$setWindowFields (etapa de agregación)

$setWindowFields

Nuevo en la versión 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.

Por ejemplo, se puede utilizar la etapa $setWindowFields para dar salida a la:

  • Diferencia de ventas entre dos documentos de una colección.

  • Clasificaciones de ventas.

  • Totales de ventas acumuladas.

  • Análisis de información compleja de series de tiempo sin exportar los datos a una base de datos externa.

La sintaxis de la etapa $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>: { ... }
}
}
}

La etapa $setWindowFields toma un documento con estos campos:

Campo
Necesidad
Descripción

partitionBy

Opcional

Especificar una expresión para agrupar los documentos. En la etapa $setWindowFields, el grupo de documentos se conoce como partición. Por defecto es una partición para toda la colección.

Requerido para algunos operadores (consultar Restricciones)

Especifica el campo o los campos por los que ordenar los documentos en la partición. Utiliza la misma sintaxis que la etapa $sort. El valor por defecto es no ordenar.

Requerido

Especifica el/los campo(s) que se agregarán a los documentos en la salida devuelta por la etapa $setWindowFields. Cada campo se establece en el resultado devuelto por el operador de ventana.

Un campo puede contener puntos para especificar campos de documentos incrustados y campos de arreglo. La semántica para la notación de puntos del documento incrustado en la etapa $setWindowFields es la misma que en las etapas $addFields y $set. Se puede consultar el ejemplo del documento incrustado $addFields y el ejemplo del documento incrustado $set.

Opcional

Especifica los límites y parámetros de la ventana. Los límites de la ventana son inclusivos. Por defecto, es un período ilimitado, que incluye todos los documentos de la partición.

Se debe especificar una ventana de documentos o de rango.

Opcional

Una ventana en la que los límites inferior y superior se especifican en relación con la posición del documento actual leído de la colección.

Los límites de la ventana se especifican mediante un arreglo de dos elementos que contiene un límite inferior y superior como string o número entero. Uso:

  • El string "current" para la posición actual del documento en la salida.

  • El string "unbounded" para la primera o la última posición del documento en la partición.

  • Un número entero para una posición relativa al documento actual. Utiliza un número entero negativo para una posición anterior al documento actual. Utiliza un número entero positivo para una posición después del documento actual. 0 es la posición actual del documento.

Se pueden consultar ejemplos de ventanas de documentos.

Opcional

Una ventana donde los límites inferior y superior se definen mediante un rango de valores basado en el campo sortBy del documento actual.

Los límites de la ventana se especifican mediante un arreglo de dos elementos que contiene un string o un número de límite inferior y superior. Uso:

  • El string "current" para la posición actual del documento en la salida.

  • El string "unbounded" para la primera o la última posición del documento en la partición.

  • Un número para agregar al valor del campo sortBy del documento actual. Un documento está en la ventana si el valor del campo sortBy está inclusive dentro de los límites inferior y superior.

Se puede consultar un ejemplo de ventana de rango.

Opcional

Especifica las unidades para los límites de la ventana de tiempo rango. Se puede configurar en una de estas cadenas:

  • "year"

  • "quarter"

  • "month"

  • "week"

  • "day"

  • "hour"

  • "minute"

  • "second"

  • "millisecond"

Si se omite, se utilizan los límites de la ventana de rango numérico por defecto.

Se pueden consultar ejemplos de ventanas de rango de tiempo.

Tip

La etapa $setWindowFields agrega nuevos campos a los documentos existentes. Puedes incluir una o más etapas $setWindowFields en una operación de agregación.

A partir de MongoDB 5.3, puedes usar la etapa $setWindowFields con transacciones y el nivel de consistencia de lectura "snapshot".

La etapa $setWindowFields no garantiza el orden de los documentos devueltos.

Estos operadores se pueden utilizar con la etapa $setWindowFields:

Restricciones para la etapa $setWindowFields:

  • Antes de MongoDB 5.3, la etapa $setWindowFields no puede utilizarse:

  • sortBy es necesario para lo siguiente:

  • Las ventanas de rango exigen que todos los valores de sortBy sean números.

  • Las ventanas de rango de tiempo requieren que todos los valores de sortBy sean fechas.

  • Las ventanas de rango y de rango de tiempo solo pueden contener un campo sortBy y la clasificación debe ser ascendente.

  • No se puede especificar una ventana de documentos y una ventana de rango a la vez.

  • Estos operadores utilizan una ventana implícita y devuelven un error si especificas una opción de ventana:

  • En las ventanas de rango, solo se incluyen en la ventana los números del rango especificado. Se excluyen los valores faltantes, indefinidos y null.

  • Para ventanas de rango de tiempo:

    • En la ventana solo se incluyen los tipos de fecha y hora.

    • Los valores de límite deben ser números enteros. Por ejemplo, puedes usar 2 horas como límite, pero no puedes usar 1,5 horas.

  • Para ventanas vacías o ventanas con valores incompatibles (por ejemplo, con $sum en strings), el valor devuelto depende del operador:

    • Para $count y $sum, el valor devuelto es 0.

    • Para $addToSet y $push, el valor devuelto es un arreglo vacío.

    • Para todos los demás operadores, el valor devuelto es null.

Crea una colección de cakeSales que incluya ventas de pasteles en el estado de California (CA) y 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 }
] )

Los siguientes ejemplos utilizan la colección cakeSales.

En este ejemplo, se utiliza una ventana de documentos en $setWindowFields para obtener la quantity de las ventas acumuladas de pasteles para cada state:

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

En el ejemplo:

  • partitionBy: "$state" particiona los documentos de la colección en state. Existen particiones para CA y WA.

  • sortBy: { orderDate: 1 } ordena los documentos de cada partición por orderDate en orden ascendente (1), de modo que el orderDate más antiguo sea el primero.

  • output:

    • Establece el campo cumulativeQuantityForState al quantity acumulado para cada state, que aumenta con sumas sucesivas al valor anterior en la partición.

    • Calcula la quantity acumulativa con el operador $sum que se ejecuta en una ventana de documentos.

      La ventana contiene documentos entre un límite inferior de unbounded y el documento current. Esto significa que $sum devuelve la quantity acumulada para los documentos entre el inicio de la partición y el documento actual.

En este resultado de ejemplo, el quantity acumulativo de CA y WA se muestra en el campo 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 }

Este ejemplo utiliza una ventana de documentos en $setWindowFields para generar las ventas acumuladas de pasteles quantity para cada $year en orderDate:

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

En el ejemplo:

  • partitionBy: { $year: "$orderDate" } particiona los documentos de la colección por $year en orderDate. Hay particiones para 2019, 2020 y 2021.

  • sortBy: { orderDate: 1 } ordena los documentos de cada partición por orderDate en orden ascendente (1), de modo que el orderDate más antiguo sea el primero.

  • output:

    • Establece el campo cumulativeQuantityForYear en la quantity acumulada de cada año, que aumenta con las sucesivas incorporaciones al valor anterior de la partición.

    • Calcula la quantity acumulativa con el operador $sum que se ejecuta en una ventana de documentos.

      La ventana contiene documentos entre un límite inferior de unbounded y el documento current. Esto significa que $sum devuelve la quantity acumulada para los documentos entre el inicio de la partición y el documento actual.

En este resultado de ejemplo, la quantity acumulativa de cada año se muestra en el campo 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 }

En este ejemplo, se utiliza una ventana de documentos en $setWindowFields para obtener el promedio móvil de las ventas de pasteles quantity:

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

En el ejemplo:

  • partitionBy: "$orderDate" particiona los documentos de la colección por $year en orderDate. Hay particiones para 2019, 2020 y 2021.

  • sortBy: { orderDate: 1 } ordena los documentos de cada partición por orderDate en orden ascendente (1), de modo que el orderDate más antiguo sea el primero.

  • output:

    • Establece el campo de averageQuantity al promedio móvil quantity de cada año.

    • Calcula el promedio móvil quantity utilizando el operador $avg que se ejecuta en una ventana de documentos.

      La ventana contiene documentos entre -1 y 0. Esto significa que $avg devuelve el promedia móvil quantity entre el documento anterior al documento actual (-1) y el documento actual (0) en la partición.

En este ejemplo de resultado, el promedio móvil quantity se muestra en el campo 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 }

En este ejemplo, se utiliza una ventana de documentos en $setWindowFields para calcular los valores acumulados y máximos de ventas de pasteles quantity de cada $year en 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" ]
}
}
}
}
}
] )

En el ejemplo:

  • partitionBy: "$orderDate" particiona los documentos de la colección por $year en orderDate. Hay particiones para 2019, 2020 y 2021.

  • sortBy: { orderDate: 1 } ordena los documentos de cada partición por orderDate en orden ascendente (1), de modo que el orderDate más antiguo sea el primero.

  • output:

    • Establece el campo cumulativeQuantityForYear en la quantity acumulada de cada año.

    • Calcula la quantity acumulativa con el operador $sum que se ejecuta en una ventana de documentos.

      La ventana contiene documentos entre un límite inferior de unbounded y el documento current. Esto significa que $sum devuelve la cantidad acumulada para los documentos entre el inicio de la partición y el documento actual.

    • Establece el campo maximumQuantityForYear en el máximo de quantity para cada año.

    • Calcula la quantity máxima de todos los documentos con el operador $max que se ejecuta en una ventana de documentos.

      La ventana contiene documentos entre un límite inferior de unbounded y upper. Esto significa que $max devuelve la cantidad máxima de documentos en la partición.

En este ejemplo de resultado, la quantity acumulada se muestra en el campo cumulativeQuantityForYear y la quantity máxima se muestra en el campo 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 }

Este ejemplo utiliza una ventana de rango en $setWindowFields para devolver la suma de los valores quantity de pasteles vendidos para pedidos dentro de más o menos 10 dólares del valor price del documento actual:

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

En el ejemplo:

  • partitionBy: "$state" particiona los documentos de la colección en state. Existen particiones para CA y WA.

  • sortBy: { price: 1 } ordena los documentos de cada partición por price en orden ascendente (1), de modo que el price más bajo sea el primero.

  • output establece el campo quantityFromSimilarOrders en la suma de los valores quantity de los documentos de una ventana de rango.

    • La ventana contiene documentos entre un límite inferior de -10 y un límite superior de 10. El rango es inclusivo.

    • $sum devuelve la suma de los valores quantity incluidos en un rango de más o menos 10 dólares del valor price del documento actual.

En este ejemplo de resultado, la suma de los valores de quantity de los documentos en la ventana se muestra en el campo 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 }

En el siguiente ejemplo, se utiliza una ventana con una unidad de rango de tiempo de límite superior positivo en $setWindowFields. El pipeline genera un arreglo de valores orderDate para cada state que coincide con el rango de tiempo especificado.

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

En el ejemplo:

  • partitionBy: "$state" particiona los documentos de la colección en state. Existen particiones para CA y WA.

  • sortBy: { orderDate: 1 } ordena los documentos de cada partición por orderDate en orden ascendente (1), de modo que el orderDate más antiguo sea el primero.

  • output:

    • Establece el campo recentOrders a un arreglo de valores de orderDate para los documentos de cada state. Los elementos del arreglo se expanden con adiciones a los elementos anteriores en el arreglo.

    • Utiliza $push para devolver un arreglo de valores orderDate de los documentos en una ventana de rango.

  • La ventana contiene documentos entre un límite inferior de unbounded y un límite superior establecido en 10 (10 meses después del valor orderDate del documento actual) y utiliza una unidad de rango de tiempo.

  • $push devuelve el arreglo de valores orderDate para los documentos entre el principio de la partición y los documentos con valores orderDate inclusive en un rango del valor orderDate del documento actual más 10 meses.

En este resultado de ejemplo, el arreglo de valores orderDate para CA y WA se muestra en el campo 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") ] }

El siguiente ejemplo utiliza una ventana con una unidad de rango de tiempo de límite superior negativo en $setWindowFields. El pipeline genera un arreglo de valores orderDate para cada state que coincide con el rango de tiempo especificado.

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

En el ejemplo:

  • partitionBy: "$state" particiona los documentos de la colección en state. Existen particiones para CA y WA.

  • sortBy: { orderDate: 1 } ordena los documentos de cada partición por orderDate en orden ascendente (1), de modo que el orderDate más antiguo sea el primero.

  • output:

    • Establece el campo recentOrders a un arreglo de valores de orderDate para los documentos de cada state. Los elementos del arreglo se expanden con adiciones a los elementos anteriores en el arreglo.

    • Utiliza $push para devolver un arreglo de valores orderDate de los documentos en una ventana de rango.

  • La ventana contiene documentos entre un límite inferior de unbounded y un límite superior establecido en -10 (10 meses antes del valor orderDate del documento actual) con una unidad de rango de tiempo.

  • $push devuelve el arreglo de valores orderDate para los documentos entre el principio de la partición y los documentos con valores orderDate inclusive dentro de un rango del valor orderDate del documento actual menos 10 meses.

En este resultado de ejemplo, el arreglo de valores orderDate para CA y WA se muestra en el campo 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") ] }

El siguiente ejemplo utiliza $setWindowFields con el operador $shift y la etapa $set para comparar campos en una colección.

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"
]
}
]
}
}
},
] )

En el ejemplo:

  • partitionBy: "$type" particiona los documentos en la colección por type para que los cálculos de cada tipo se mantengan separados.

  • sortBy: { orderDate: 1 } ordena los documentos de cada partición por orderDate en orden ascendente (1).

  • output.previousPrice utiliza el operador $shift para capturar el price del orden inmediato anterior dentro del mismo año.

  • $set añade un nuevo campo denominado priceComparison y establece el valor de ese campo en higher, lower o same en función de la comparación con previousPrice.

En este resultado de ejemplo, el resultado de la comparación se muestra en el campo priceComparison:

[
{
_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'
}
]

La siguiente clase WeatherMeasurement representa documentos de una colección de mediciones meteorológicas:

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()método en un PipelineDefinition objeto.

En el siguiente ejemplo, se crea una etapa de pipeline que utiliza los campos Rainfall y Temperature para calcular la precipitación acumulada, la temperatura promedio móvil, la temperatura mediana y la precipitación del percentil 90 durante el último mes para cada localidad:

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)
),
MedianTemperature = o.Median(
w => w.Temperature,
RangeWindow.Create(
RangeWindow.Months(-1),
RangeWindow.Current)
),
NinetiethPercentileRainfall = o.Percentile(
w => w.Rainfall,
new[] { 0.9 },
RangeWindow.Create(
RangeWindow.Months(-1),
RangeWindow.Current)
)
}
);

Los ejemplos de Node.js en esta página utilizan la colección sample_weatherdata.data de los conjuntos de datos de muestra de Atlas. Para aprender a crear un clúster gratuito de MongoDB Atlas y cargar los conjuntos de datos de muestra, se puede consultar Primeros pasos en la documentación del driver de MongoDB Node.js.

Para utilizar el controlador de MongoDB Node.js para agregar una etapa de $setWindowFields a una canalización de agregación, utilice el Operador $setWindowFields en un objeto de canalización.

El siguiente ejemplo crea una etapa del pipeline que calcula el airTemperature.value promedio y el waveMeasurement.waves.height total para cada valor único de callLetters durante el último mes. A continuación, el ejemplo ejecuta el pipeline de agregación:

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

Para un ejemplo adicional sobre IOT Power Consumption, see the Practical MongoDB Aggregations e-book.

Volver

$set

En esta página