Definición
Nuevo en la versión 5.0.
Realiza operaciones en un intervalo especificado de documentos de una colección, conocido como ventana, y devuelve los resultados en función del operador de ventana elegido.
Por ejemplo, puede utilizar la $setWindowFields etapa para generar la siguiente salida:
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.
Sintaxis
La sintaxis de la $setWindowFields etapa:
{ $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 toma un documento con estos $setWindowFields campos:
Campo | Necesidad | Descripción |
|---|---|---|
Opcional | Especifica una expresión para agrupar los documentos. En la | |
Requerido para algunos operadores (se puede 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 | |
Requerido | Especifica el/los campo(s) que se añadirán a los documentos en la salida devuelta por la etapa. Cada campo se establece con el resultado devuelto por el Un campo puede contener puntos para especificar campos de documento incrustados y campos de matriz. La semántica para la notación de puntos de documento incrustado en la
| |
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:
| |
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:
| |
Opcional | Especifica las unidades para los límites de la ventana de intervalo de tiempo. Se puede establecer en una de estas cadenas:
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
Comportamiento
La etapa agrega nuevos campos a los $setWindowFields $setWindowFields documentos existentes. Puede incluir una o más etapas en una operación de agregación.
A partir de MongoDB,5.3 puede utilizar la $setWindowFields etapa con transacciones y la preocupación "snapshot" de lectura.
La etapa $setWindowFields no garantiza el orden de los documentos devueltos.
Operadores de ventana
Estos operadores se pueden utilizar con la $setWindowFields etapa:
- Operadores de acumulación:
$addToSet,$avg,$bottom,$bottomN,$concatArrays,$count,$covariancePop,$covarianceSamp,$derivative,$expMovingAvg,$firstN,$integral,$lastN,$max,$maxN,$median,$mergeObjects,$min,$minN,$percentile,$push,$setUnion,$stdDevSamp,$stdDevPop,$sum,$top,$topN.
- Operadores de relleno de vacíos:
$linearFilly$locf.
Operadores de rango:
$denseRank,$documentNumbery$rank.Operador de rango:
$minMaxScaler
Explicar la salida
Nuevo en la versión 8.3.
Si ejecutas explain en una operación $setWindowsFields, la salida contiene un campo peakTrackedMemBytes que muestra el número máximo de bytes de memoria rastreada en uso. Para obtener más información, consulte explain.executionStats.peakTrackedMemBytes.
Restricciones
Restricciones para la $setWindowFields etapa:
Antes de MongoDB,5.3 no se puede utilizar
$setWindowFieldsla etapa:en transacciones;
con
"snapshot"nivel de consistencia de lectura.
sortBy es necesario para lo siguiente:
Ventanas delimitadas (ya sea una ventana de documentos o una ventana de rango).
$linearFilloperador.
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.
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
$sumen strings), el valor devuelto depende del operador:Para todos los demás operadores, el valor devuelto es
null.
Ejemplos
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.
Ejemplos de ventanas de documentos
Usa la ventana de documentos para obtener la cantidad acumulada para cada estado
Este ejemplo utiliza una ventana de documentos en para mostrar las ventas acumuladas de $setWindowFields pasteles quantity para state cada:
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ónstatepor. Hay particionesCAparaWAy.sortBy: { orderDate: 1 }ordena los documentos en cada partición pororderDateen orden ascendente1(), de modo que el más antiguoorderDatees el primero.
output:Establece el campo
cumulativeQuantityForStatealquantityacumulado para cadastate, que aumenta con sumas sucesivas al valor anterior en la partición.Calcula la
quantityacumulativa con el operador$sumque se ejecuta en una ventana de documentos.La ventana contiene documentos entre un
unboundedlímite inferior y elcurrentdocumento. Esto significa que$sumdevuelve el acumulativoquantitypara 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 }
Usa la ventana de documentos para obtener la cantidad acumulada de cada año.
Este ejemplo utiliza una ventana de documentos en para mostrar las ventas acumuladas de $setWindowFields pasteles quantity para cada $year orderDateen:
db.cakeSales.aggregate( [ { $setWindowFields: { partitionBy: { $year: "$orderDate" }, sortBy: { orderDate: 1 }, output: { cumulativeQuantityForYear: { $sum: "$quantity", window: { documents: [ "unbounded", "current" ] } } } } } ] )
En el ejemplo:
sortBy: { orderDate: 1 }ordena los documentos en cada partición pororderDateen orden ascendente1(), de modo que el más antiguoorderDatees el primero.output:Establece el campo
cumulativeQuantityForYearen laquantityacumulada de cada año, que aumenta con las sucesivas incorporaciones al valor anterior de la partición.Calcula la
quantityacumulativa con el operador$sumque se ejecuta en una ventana de documentos.La ventana contiene documentos entre un
unboundedlímite inferior y elcurrentdocumento. Esto significa que$sumdevuelve el acumulativoquantitypara 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 }
Usa la ventana de documentos para obtener el promedio móvil de cada año.
Este ejemplo utiliza una ventana de documentos en para mostrar el promedio móvil de las ventas $setWindowFields de quantity pasteles:
db.cakeSales.aggregate( [ { $setWindowFields: { partitionBy: { $year: "$orderDate" }, sortBy: { orderDate: 1 }, output: { averageQuantity: { $avg: "$quantity", window: { documents: [ -1, 0 ] } } } } } ] )
En el ejemplo:
sortBy: { orderDate: 1 }ordena los documentos en cada partición pororderDateen orden ascendente1(), de modo que el más antiguoorderDatees el primero.output:Establece el campo de
averageQuantityal promedio móvilquantityde cada año.Calcula el promedio móvil
quantityutilizando el operador$avgque se ejecuta en una ventana de documentos.La ventana contiene documentos entre
-10y. Esto significa que$avgdevuelve la media móvilquantityentre el documento anterior al documento actual-1() y el documento actual0() 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 }
Utiliza la ventana de documentos para obtener la cantidad acumulada y máxima de cada año
Este ejemplo utiliza una ventana de documentos en para mostrar los valores acumulados y máximos de ventas de $setWindowFields pasteles quantity para cada $year orderDateen:
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:
sortBy: { orderDate: 1 }ordena los documentos en cada partición pororderDateen orden ascendente1(), de modo que el más antiguoorderDatees el primero.output:Establece el campo
cumulativeQuantityForYearen laquantityacumulada de cada año.Calcula la
quantityacumulativa con el operador$sumque se ejecuta en una ventana de documentos.La ventana contiene documentos entre un
unboundedlímite inferior y elcurrentdocumento. Esto significa que$sumdevuelve la cantidad acumulada de documentos entre el inicio de la partición y el documento actual.Establece el campo
maximumQuantityForYearen el máximo dequantitypara cada año.Calcula la
quantitymáxima de todos los documentos con el operador$maxque se ejecuta en una ventana de documentos.La ventana contiene documentos entre un
unboundedlímite inferior y unupperlímite. Esto significa que$maxdevuelve 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 }
Ejemplo de ventana de rango
Este ejemplo utiliza una ventana de rango en para devolver la suma de $setWindowFields los quantity valores de pasteles vendidos para pedidos dentro de más o menos 10 dólares del price valor 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ónstatepor. Hay particionesCAparaWAy.sortBy: { price: 1 }ordena los documentos en cada partición porpriceen orden ascendente1(), de modo que el más bajopriceestá primero.outputestablece el campoquantityFromSimilarOrdersen la suma de los valoresquantityde los documentos de una ventana de rango.
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 }
Ejemplos de ventanas de rango de tiempo
Utiliza una ventana de rango de tiempo con un límite superior positivo.
El siguiente ejemplo utiliza una ventana con un rango de tiempo de límite superior positivo $setWindowFieldsen. La canalización genera una matriz de orderDate valores para cada state que coinciden 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ónstatepor. Hay particionesCAparaWAy.sortBy: { orderDate: 1 }ordena los documentos en cada partición pororderDateen orden ascendente1(), de modo que el más antiguoorderDatees el primero.output:Establece el campo
recentOrdersa un arreglo de valores deorderDatepara los documentos de cadastate. Los elementos del arreglo se expanden con adiciones a los elementos anteriores en el arreglo.
La ventana contiene documentos entre un
unboundedlímite inferior y un límite superior establecido en10(10 meses después del valor del documentoorderDateactual) utilizando una unidad de rango de tiempo.$pushdevuelve el arreglo de valoresorderDatepara los documentos entre el principio de la partición y los documentos con valoresorderDateinclusive en un rango del valororderDatedel documento actual más10meses.
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") ] }
Utiliza una ventana de rango temporal con un límite superior negativo.
El siguiente ejemplo utiliza una ventana con un rango de tiempo de límite superior negativo $setWindowFieldsen. La canalización genera una matriz de orderDate valores para cada state que coinciden 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ónstatepor. Hay particionesCAparaWAy.sortBy: { orderDate: 1 }ordena los documentos en cada partición pororderDateen orden ascendente1(), de modo que el más antiguoorderDatees el primero.output:Establece el campo
recentOrdersa un arreglo de valores deorderDatepara los documentos de cadastate. Los elementos del arreglo se expanden con adiciones a los elementos anteriores en el arreglo.
La ventana contiene documentos entre un
unboundedlímite inferior y un límite superior establecido en-10(10 meses antes del valor del documentoorderDateactual) utilizando una unidad de rango de tiempo.$pushdevuelve el arreglo de valoresorderDatepara los documentos entre el principio de la partición y los documentos con valoresorderDateinclusive dentro de un rango del valororderDatedel documento actual menos10meses.
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") ] }
Ejemplo de comparación con valores anteriores
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"divide los documentos de la colección portypede modo que los cálculos de cada tipo se mantienen separados.sortBy: { orderDate: 1 }ordena los documentos en cada partición pororderDateen orden ascendente1().output.previousPriceutiliza el operador$shiftpara capturar elpricedel orden inmediato anterior dentro del mismo año.$setañade un nuevo campo denominadopriceComparisony establece el valor de ese campo enhigher,lowerosameen función de la comparación conpreviousPrice.
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 ObjectId Id { get; set; } [] public string LocalityId { get; set; } = null!; [] public DateTime MeasurementDateTime { get; set; } [] public float Rainfall { get; set; } [] public float Temperature { get; set; } }
Para usar el controlador MongoDB.NET/C# para agregar una $setWindowFields etapa a una canalización de agregación, llame al método UnionWith() 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) ) } );
{ "_id" : "...", "localityId" : "L1", "measurementDateTime" : "...", "rainfall" : 5.0, "temperature" : 20.0, "MonthlyRainfall" : 5.0, "TemperatureAvg" : 20.0, "MedianTemperature" : 20.0, "NinetiethPercentileRainfall" : [5.0] } { "_id" : "...", "localityId" : "L1", "measurementDateTime" : "...", "rainfall" : 10.0, "temperature" : 25.0, "MonthlyRainfall" : 10.0, "TemperatureAvg" : 25.0, "MedianTemperature" : 25.0, "NinetiethPercentileRainfall" : [10.0] } { "_id" : "...", "localityId" : "L1", "measurementDateTime" : "...", "rainfall" : 8.0, "temperature" : 22.0, "MonthlyRainfall" : 8.0, "TemperatureAvg" : 22.0, "MedianTemperature" : 22.0, "NinetiethPercentileRainfall" : [8.0] } { "_id" : "...", "localityId" : "L2", "measurementDateTime" : "...", "rainfall" : 6.0, "temperature" : 18.0, "MonthlyRainfall" : 6.0, "TemperatureAvg" : 18.0, "MedianTemperature" : 18.0, "NinetiethPercentileRainfall" : [6.0] } { "_id" : "...", "localityId" : "L2", "measurementDateTime" : "...", "rainfall" : 6.0, "temperature" : 18.0, "MonthlyRainfall" : 12.0, "TemperatureAvg" : 18.0, "MedianTemperature" : 18.0, "NinetiethPercentileRainfall" : [6.0] }
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, consulte Primeros pasos en la documentación del controlador 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 ver otro ejemplo sobre el consumo energético IOT, consulta el libro electrónico Agregaciones prácticas de MongoDB.