Para agentes de IA: hay un índice de documentación disponible en https://www.mongodb.com/es/docs/llms.txt — versiones en markdown de todas las páginas están disponibles agregando .md a cualquier ruta URL.
Docs Menu

$setWindowFields (etapa de agregación)

$setWindowFields

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.

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 $setWindowFields etapa, el grupo de documentos se conoce como partición.Por defecto, se crea una partición para toda la colección.

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 $sort. El valor por defecto es no ordenar.

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 $setWindowFields operadorde ventana.

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 $setWindowFields etapa es la misma que en las $addFields $set etapas y. Consulte el ejemplo de $addFields de documento incrustado y el ejemplo de $set de documento incrustado.

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.

Consulte los ejemplos de la ventana 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.

Consulte el ejemplo de ventana de rango.

Opcional

Especifica las unidades para los límites de la ventana de intervalo de tiempo. Se puede establecer 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.

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.

Estos operadores se pueden utilizar con la $setWindowFields etapa:

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 para la $setWindowFields etapa:

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

  • 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:

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

  • 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.

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ón state por. Hay particiones CA para WA y.

  • sortBy: { orderDate: 1 } ordena los documentos en cada partición por orderDate en orden ascendente1 (), de modo que el más antiguo orderDate es 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 unbounded límite inferior y el current documento. Esto significa que $sum devuelve el acumulativo quantity 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 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:

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

  • sortBy: { orderDate: 1 } ordena los documentos en cada partición por orderDate en orden ascendente1 (), de modo que el más antiguo orderDate es 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 unbounded límite inferior y el current documento. Esto significa que $sum devuelve el acumulativo quantity 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 }

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:

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

  • sortBy: { orderDate: 1 } ordena los documentos en cada partición por orderDate en orden ascendente1 (), de modo que el más antiguo orderDate es 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 0y. Esto significa que $avg devuelve la media móvil quantity entre 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 }

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:

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

  • sortBy: { orderDate: 1 } ordena los documentos en cada partición por orderDate en orden ascendente1 (), de modo que el más antiguo orderDate es 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 unbounded límite inferior y el current documento. Esto significa que $sum devuelve la cantidad acumulada de 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 unbounded límite inferior y un upper límite. 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 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ón state por. Hay particiones CA para WA y.

  • sortBy: { price: 1 } ordena los documentos en cada partición por price en orden ascendente1 (), de modo que el más bajo price está 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 comprendidos entre un límite inferior de -10 y un límite superior 10 de. 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 }

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ón state por. Hay particiones CA para WA y.

  • sortBy: { orderDate: 1 } ordena los documentos en cada partición por orderDate en orden ascendente1 (), de modo que el más antiguo orderDate es 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 unbounded límite inferior y un límite superior establecido en 10 (10 meses después del valor del documento orderDate actual) utilizando 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 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ón state por. Hay particiones CA para WA y.

  • sortBy: { orderDate: 1 } ordena los documentos en cada partición por orderDate en orden ascendente1 (), de modo que el más antiguo orderDate es 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 unbounded límite inferior y un límite superior establecido en -10 (10 meses antes del valor del documento orderDate actual) utilizando 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" divide los documentos de la colección por type de modo que los cálculos de cada tipo se mantienen separados.

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

  • 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:

[BsonIgnoreExtraElements]
public class WeatherMeasurement
{
[BsonId]
public ObjectId Id { get; set; }
[BsonElement("localityId")]
public string LocalityId { get; set; } = null!;
[BsonElement("measurementDateTime")]
public DateTime MeasurementDateTime { get; set; }
[BsonElement("rainfall")]
public float Rainfall { get; set; }
[BsonElement("temperature")]
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.