Para agentes de IA: um índice de documentação está disponível em https://www.mongodb.com/pt-br/docs/llms.txt — as versões de markdown de todas as páginas estão disponíveis anexando .md a qualquer caminho de URL.
Menu Docs

$setWindowFields (estágio de agregação )

$setWindowFields

Novidade na versão 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:

  • Diferença nas vendas entre dois documentos em uma coleção.

  • Classificações de vendas.

  • Total cumulativo de vendas.

  • Análise de informações complexas de séries temporais sem exportar os dados para um banco de dados externo.

The $setWindowFields stage syntax:

{
$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:

Campo
necessidade
Descrição

Opcional

Specifies an expression to group the documents. In the $setWindowFields stage, the group of documents is known as a partition. Default is one partition for the entire collection.

Required for some operators (see Restrictions)

Especifica o(s) campo(s) para classificar os documentos na partição. Usa a mesma sintaxe do estágio $sort. O padrão não está classificando.

Obrigatório

Specifies the field(s) to append to the documents in the output returned by the $setWindowFields stage. 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. See embedded document $addFields example and embedded document $set example.

Opcional

Especifica os parâmetros e limites da janela. Os limites da janela são inclusivos. O padrão é uma janela sem limite, que inclui todos os documentos na partição.

Especifique uma janela de documentos ou faixa.

Opcional

Uma janela onde os limites inferior e superior são especificados em relação à posição do documento atual lido na collection.

Os limites da janela são especificados usando uma array de dois elementos contendo uma string ou número inteiro de limite inferior e superior. Usar:

  • A string "current" para a posição atual do documento no resultado.

  • A string "unbounded" para a posição do primeiro ou último documento na partição.

  • Um número inteiro para uma posição relativa ao documento atual. Use um número inteiro negativo para uma posição antes do documento atual. Use um número inteiro positivo para uma posição após o documento atual. 0 é a posição atual do documento.

Consulte Exemplos de janelas de documentos.

Opcional

A window where the lower and upper boundaries are defined using a range of values based on the sortBy field in the current document.

Os limites da janela são especificados usando uma array de dois elementos contendo uma string ou número de limite inferior e superior. Usar:

  • A string "current" para a posição atual do documento no resultado.

  • A string "unbounded" para a posição do primeiro ou último documento na partição.

  • Um número a ser adicionado ao valor do campo sortBy do documento atual. Um documento estará na janela se o valor do campo sortBy estiver inclusive dentro dos limites inferior e superior.

Consulte Exemplo de janela de faixa.

Opcional

Especifica as unidades para os limites da janela de faixa de tempo. Pode-se definir como uma destas strings:

  • "year"

  • "quarter"

  • "month"

  • "week"

  • "day"

  • "hour"

  • "minute"

  • "second"

  • "millisecond"

If omitted, default numeric range window boundaries are used.

Consulte Exemplos de janela de faixa de tempo.

The $setWindowFields stage appends new fields to existing documents. You can include one or more $setWindowFields stages in an aggregation operation.

Starting in MongoDB 5.3, you can use the $setWindowFields stage with transactions and the "snapshot" read concern.

O estágio $setWindowFields não garante a ordem dos documentos retornados.

These operators can be used with the $setWindowFields stage:

Novidades na versão 8.3.

Se você executar explain em uma operação $setWindowsFields, a saída conterá um campo peakTrackedMemBytes que contém o número máximo de bytes de memória monitorada em uso. Para mais informações, consulte explain.executionStats.peakTrackedMemBytes.

Restrictions for the $setWindowFields stage:

  • Before MongoDB 5.3, the $setWindowFields stage cannot be used:

  • sortBy is required for:

  • As janelas de faixa exigem que todos os valores sortBy sejam números.

  • As janelas de faixa de tempo exigem que todos os valores de sortBy sejam datas.

  • As janelas de faixa e faixa de tempo só podem conter um campo sortBy e a ordem deve ser ascendente.

  • You cannot specify both a documents window and a range window.

  • Estes operadores usam uma janela implícita e retornam um erro se você especificar uma opção de janela:

  • For range windows, only numbers in the specified range are included in the window. Missing, undefined, and null values are excluded.

  • For time range windows:

    • Somente tipos de data e hora são incluídos na janela.

    • Os valores de limite numéricos devem ser inteiros. Por exemplo, você pode usar 2 horas como limite, mas não pode usar 1,5 hora.

  • Para janelas vazias ou janelas com valores incompatíveis (por exemplo, utilizando $sum em strings), o valor retornado depende do operador:

    • Para $count e $sum, o valor retornado é 0.

    • Para $addToSet e $push, o valor retornado é uma array vazia.

    • Para todos os outros operadores, o valor retornado é null.

Crie uma collection cakeSales que contenha vendas de bolo nos estados da Califórnia (CA) e de 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 }
] )

Os exemplos a seguir usam a collection cakeSales.

This example uses a documents window in $setWindowFields to output the cumulative cake sales quantity for each state. In the example output, the cumulativeQuantityForState field shows the cumulative quantity for CA and WA.

db.cakeSales.aggregate( [
{
$setWindowFields: {
partitionBy: "$state",
sortBy: { orderDate: 1 },
output: {
cumulativeQuantityForState: {
$sum: "$quantity",
window: {
documents: [ "unbounded", "current" ]
}
}
}
}
}
] )
[
{
_id: 4,
type: 'strawberry',
orderDate: ISODate('2019-05-18T16:09:01.000Z'),
state: 'CA',
price: 41,
quantity: 162,
cumulativeQuantityForState: 162
},
{
_id: 0,
type: 'chocolate',
orderDate: ISODate('2020-05-18T14:10:30.000Z'),
state: 'CA',
price: 13,
quantity: 120,
cumulativeQuantityForState: 282
},
{
_id: 2,
type: 'vanilla',
orderDate: ISODate('2021-01-11T06:31:15.000Z'),
state: 'CA',
price: 12,
quantity: 145,
cumulativeQuantityForState: 427
},
{
_id: 5,
type: 'strawberry',
orderDate: ISODate('2019-01-08T06:12:03.000Z'),
state: 'WA',
price: 43,
quantity: 134,
cumulativeQuantityForState: 134
},
{
_id: 3,
type: 'vanilla',
orderDate: ISODate('2020-02-08T13:13:23.000Z'),
state: 'WA',
price: 13,
quantity: 104,
cumulativeQuantityForState: 238
},
{
_id: 1,
type: 'chocolate',
orderDate: ISODate('2021-03-20T11:30:05.000Z'),
state: 'WA',
price: 14,
quantity: 140,
cumulativeQuantityForState: 378
}
]

No exemplo:

  • partitionBy: "$state" partitions the documents in the collection by state. There are partitions for CA and WA.

  • sortBy: { orderDate: 1 } sorts the documents in each partition by orderDate in ascending order (1), so the earliest orderDate is first.

  • output:

    • Define o campo cumulativeQuantityForState para o quantity cumulativo para cada state, o que aumenta sucessivamente ao valor anterior na partição.

    • Calcula o quantity cumulativo utilizando o operador $sum executado em uma janela de documentos.

      The window contains documents between an unbounded lower limit and the current document. This means $sum returns the cumulative quantity for the documents between the beginning of the partition and the current document.

This example uses a documents window in $setWindowFields to output the cumulative cake sales quantity for each $year in orderDate. In the example output, the cumulativeQuantityForYear field shows the cumulative quantity for each year.

db.cakeSales.aggregate( [
{
$setWindowFields: {
partitionBy: { $year: "$orderDate" },
sortBy: { orderDate: 1 },
output: {
cumulativeQuantityForYear: {
$sum: "$quantity",
window: {
documents: [ "unbounded", "current" ]
}
}
}
}
}
] )
[
{
_id: 5,
type: 'strawberry',
orderDate: ISODate('2019-01-08T06:12:03.000Z'),
state: 'WA',
price: 43,
quantity: 134,
cumulativeQuantityForYear: 134
},
{
_id: 4,
type: 'strawberry',
orderDate: ISODate('2019-05-18T16:09:01.000Z'),
state: 'CA',
price: 41,
quantity: 162,
cumulativeQuantityForYear: 296
},
{
_id: 3,
type: 'vanilla',
orderDate: ISODate('2020-02-08T13:13:23.000Z'),
state: 'WA',
price: 13,
quantity: 104,
cumulativeQuantityForYear: 104
},
{
_id: 0,
type: 'chocolate',
orderDate: ISODate('2020-05-18T14:10:30.000Z'),
state: 'CA',
price: 13,
quantity: 120,
cumulativeQuantityForYear: 224
},
{
_id: 2,
type: 'vanilla',
orderDate: ISODate('2021-01-11T06:31:15.000Z'),
state: 'CA',
price: 12,
quantity: 145,
cumulativeQuantityForYear: 145
},
{
_id: 1,
type: 'chocolate',
orderDate: ISODate('2021-03-20T11:30:05.000Z'),
state: 'WA',
price: 14,
quantity: 140,
cumulativeQuantityForYear: 285
}
]

No exemplo:

  • partitionBy: { $year: "$orderDate" } partitions the documents in the collection by $year in orderDate. There are partitions for 2019, 2020, and 2021.

  • sortBy: { orderDate: 1 } sorts the documents in each partition by orderDate in ascending order (1), so the earliest orderDate is first.

  • output:

    • Define o campo cumulativeQuantityForYear para o quantity cumulativo para cada ano, que aumenta sucessivamente o valor anterior na partição.

    • Calcula o quantity cumulativo utilizando o operador $sum executado em uma janela de documentos.

      The window contains documents between an unbounded lower limit and the current document. This means $sum returns the cumulative quantity for the documents between the beginning of the partition and the current document.

This example uses a documents window in $setWindowFields to output the moving average for the cake sales quantity. In the example output, the averageQuantity field shows the moving average quantity.

db.cakeSales.aggregate( [
{
$setWindowFields: {
partitionBy: { $year: "$orderDate" },
sortBy: { orderDate: 1 },
output: {
averageQuantity: {
$avg: "$quantity",
window: {
documents: [ -1, 0 ]
}
}
}
}
}
] )
[
{
_id: 5,
type: 'strawberry',
orderDate: ISODate('2019-01-08T06:12:03.000Z'),
state: 'WA',
price: 43,
quantity: 134,
averageQuantity: 134
},
{
_id: 4,
type: 'strawberry',
orderDate: ISODate('2019-05-18T16:09:01.000Z'),
state: 'CA',
price: 41,
quantity: 162,
averageQuantity: 148
},
{
_id: 3,
type: 'vanilla',
orderDate: ISODate('2020-02-08T13:13:23.000Z'),
state: 'WA',
price: 13,
quantity: 104,
averageQuantity: 104
},
{
_id: 0,
type: 'chocolate',
orderDate: ISODate('2020-05-18T14:10:30.000Z'),
state: 'CA',
price: 13,
quantity: 120,
averageQuantity: 112
},
{
_id: 2,
type: 'vanilla',
orderDate: ISODate('2021-01-11T06:31:15.000Z'),
state: 'CA',
price: 12,
quantity: 145,
averageQuantity: 145
},
{
_id: 1,
type: 'chocolate',
orderDate: ISODate('2021-03-20T11:30:05.000Z'),
state: 'WA',
price: 14,
quantity: 140,
averageQuantity: 142.5
}
]

No exemplo:

  • partitionBy: "$orderDate" partitions the documents in the collection by $year in orderDate. There are partitions for 2019, 2020, and 2021.

  • sortBy: { orderDate: 1 } sorts the documents in each partition by orderDate in ascending order (1), so the earliest orderDate is first.

  • output:

    • Define o campo averageQuantity para a média móvel quantity para cada ano.

    • Calculates the moving average quantity using the $avg operator run in a documents window.

      The window contains documents between -1 and 0. This means $avg returns the moving average quantity between the document before the current document (-1) and the current document (0) in the partition.

This example uses a documents window in $setWindowFields to output the cumulative and maximum cake sales quantity values for each $year in orderDate. In the example output, the cumulativeQuantityForYear field shows the cumulative quantity and the maximumQuantityForYear field shows the maximum quantity.

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" ]
}
}
}
}
}
] )
[
{
_id: 5,
type: 'strawberry',
orderDate: ISODate('2019-01-08T06:12:03.000Z'),
state: 'WA',
price: 43,
quantity: 134,
cumulativeQuantityForYear: 134,
maximumQuantityForYear: 162
},
{
_id: 4,
type: 'strawberry',
orderDate: ISODate('2019-05-18T16:09:01.000Z'),
state: 'CA',
price: 41,
quantity: 162,
cumulativeQuantityForYear: 296,
maximumQuantityForYear: 162
},
{
_id: 3,
type: 'vanilla',
orderDate: ISODate('2020-02-08T13:13:23.000Z'),
state: 'WA',
price: 13,
quantity: 104,
cumulativeQuantityForYear: 104,
maximumQuantityForYear: 120
},
{
_id: 0,
type: 'chocolate',
orderDate: ISODate('2020-05-18T14:10:30.000Z'),
state: 'CA',
price: 13,
quantity: 120,
cumulativeQuantityForYear: 224,
maximumQuantityForYear: 120
},
{
_id: 2,
type: 'vanilla',
orderDate: ISODate('2021-01-11T06:31:15.000Z'),
state: 'CA',
price: 12,
quantity: 145,
cumulativeQuantityForYear: 145,
maximumQuantityForYear: 145
},
{
_id: 1,
type: 'chocolate',
orderDate: ISODate('2021-03-20T11:30:05.000Z'),
state: 'WA',
price: 14,
quantity: 140,
cumulativeQuantityForYear: 285,
maximumQuantityForYear: 145
}
]

No exemplo:

  • partitionBy: "$orderDate" partitions the documents in the collection by $year in orderDate. There are partitions for 2019, 2020, and 2021.

  • sortBy: { orderDate: 1 } sorts the documents in each partition by orderDate in ascending order (1), so the earliest orderDate is first.

  • output:

    • Define o campo cumulativeQuantityForYear como quantity cumulativo para cada ano.

    • Calcula o quantity cumulativo utilizando o operador $sum executado em uma janela de documentos.

      The window contains documents between an unbounded lower limit and the current document. This means $sum returns the cumulative quantity for the documents between the beginning of the partition and the current document.

    • Define o campo maximumQuantityForYear para a quantity máxima para cada ano.

    • Calcula a quantity máxima de todos os documentos usando o operador $max executado em uma janela de documentos.

      The window contains documents between an unbounded lower and upper limit. This means $max returns the maximum quantity for the documents in the partition.

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. In the example output, the quantityFromSimilarOrders field shows the sum of the quantity values for documents in the window.

db.cakeSales.aggregate( [
{
$setWindowFields: {
partitionBy: "$state",
sortBy: { price: 1 },
output: {
quantityFromSimilarOrders: {
$sum: "$quantity",
window: {
range: [ -10, 10 ]
}
}
}
}
}
] )
[
{
_id: 2,
type: 'vanilla',
orderDate: ISODate('2021-01-11T06:31:15.000Z'),
state: 'CA',
price: 12,
quantity: 145,
quantityFromSimilarOrders: 265
},
{
_id: 0,
type: 'chocolate',
orderDate: ISODate('2020-05-18T14:10:30.000Z'),
state: 'CA',
price: 13,
quantity: 120,
quantityFromSimilarOrders: 265
},
{
_id: 4,
type: 'strawberry',
orderDate: ISODate('2019-05-18T16:09:01.000Z'),
state: 'CA',
price: 41,
quantity: 162,
quantityFromSimilarOrders: 162
},
{
_id: 3,
type: 'vanilla',
orderDate: ISODate('2020-02-08T13:13:23.000Z'),
state: 'WA',
price: 13,
quantity: 104,
quantityFromSimilarOrders: 244
},
{
_id: 1,
type: 'chocolate',
orderDate: ISODate('2021-03-20T11:30:05.000Z'),
state: 'WA',
price: 14,
quantity: 140,
quantityFromSimilarOrders: 244
},
{
_id: 5,
type: 'strawberry',
orderDate: ISODate('2019-01-08T06:12:03.000Z'),
state: 'WA',
price: 43,
quantity: 134,
quantityFromSimilarOrders: 134
}
]

No exemplo:

  • partitionBy: "$state" partitions the documents in the collection by state. There are partitions for CA and WA.

  • sortBy: { price: 1 } sorts the documents in each partition by price in ascending order (1), so the lowest price is first.

  • output define o campo quantityFromSimilarOrders como a soma dos valores quantity dos documentos em uma janela de faixa.

    • The window contains documents between a lower limit of -10 and an upper limit of 10. The range is inclusive.

    • $sum retorna a soma de valores quantity contidos em uma faixa de mais ou menos 10 dólares do valor price do documento atual.

The following example uses a window with a positive upper bound time range unit in $setWindowFields. The pipeline outputs an array of orderDate values for each state that match the specified time range. In the example output, the recentOrders field shows the array of orderDate values for CA and WA.

db.cakeSales.aggregate( [
{
$setWindowFields: {
partitionBy: "$state",
sortBy: { orderDate: 1 },
output: {
recentOrders: {
$push: "$orderDate",
window: {
range: [ "unbounded", 10 ],
unit: "month"
}
}
}
}
}
] )
[
{
_id: 4,
type: 'strawberry',
orderDate: ISODate('2019-05-18T16:09:01.000Z'),
state: 'CA',
price: 41,
quantity: 162,
recentOrders: [
ISODate('2019-05-18T16:09:01.000Z')
]
},
{
_id: 0,
type: 'chocolate',
orderDate: ISODate('2020-05-18T14:10:30.000Z'),
state: 'CA',
price: 13,
quantity: 120,
recentOrders: [
ISODate('2019-05-18T16:09:01.000Z'),
ISODate('2020-05-18T14:10:30.000Z'),
ISODate('2021-01-11T06:31:15.000Z')
]
},
{
_id: 2,
type: 'vanilla',
orderDate: ISODate('2021-01-11T06:31:15.000Z'),
state: 'CA',
price: 12,
quantity: 145,
recentOrders: [
ISODate('2019-05-18T16:09:01.000Z'),
ISODate('2020-05-18T14:10:30.000Z'),
ISODate('2021-01-11T06:31:15.000Z')
]
},
{
_id: 5,
type: 'strawberry',
orderDate: ISODate('2019-01-08T06:12:03.000Z'),
state: 'WA',
price: 43,
quantity: 134,
recentOrders: [
ISODate('2019-01-08T06:12:03.000Z')
]
},
{
_id: 3,
type: 'vanilla',
orderDate: ISODate('2020-02-08T13:13:23.000Z'),
state: 'WA',
price: 13,
quantity: 104,
recentOrders: [
ISODate('2019-01-08T06:12:03.000Z'),
ISODate('2020-02-08T13:13:23.000Z')
]
},
{
_id: 1,
type: 'chocolate',
orderDate: ISODate('2021-03-20T11:30:05.000Z'),
state: 'WA',
price: 14,
quantity: 140,
recentOrders: [
ISODate('2019-01-08T06:12:03.000Z'),
ISODate('2020-02-08T13:13:23.000Z'),
ISODate('2021-03-20T11:30:05.000Z')
]
}
]

No exemplo:

  • partitionBy: "$state" partitions the documents in the collection by state. There are partitions for CA and WA.

  • sortBy: { orderDate: 1 } sorts the documents in each partition by orderDate in ascending order (1), so the earliest orderDate is first.

  • output:

    • Define o campo recentOrders para uma array de valores orderDate para os documentos em cada state. Os elementos de array são expandidos com adições aos elementos anteriores na array.

    • Usa $push para retornar uma array de valores orderDate dos documentos em uma janela de faixa.

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

  • $push retorna a array de valores orderDate para os documentos entre o início da partição e os documentos com valores orderDate inclusive em uma faixa do valor orderDate do documento atual mais 10 meses.

The following example uses a window with a negative upper bound time range unit in $setWindowFields. The pipeline outputs an array of orderDate values for each state that match the specified time range. In the example output, the recentOrders field shows the array of orderDate values for CA and WA.

db.cakeSales.aggregate( [
{
$setWindowFields: {
partitionBy: "$state",
sortBy: { orderDate: 1 },
output: {
recentOrders: {
$push: "$orderDate",
window: {
range: [ "unbounded", -10 ],
unit: "month"
}
}
}
}
}
] )
[
{
_id: 4,
type: 'strawberry',
orderDate: ISODate('2019-05-18T16:09:01.000Z'),
state: 'CA',
price: 41,
quantity: 162,
recentOrders: []
},
{
_id: 0,
type: 'chocolate',
orderDate: ISODate('2020-05-18T14:10:30.000Z'),
state: 'CA',
price: 13,
quantity: 120,
recentOrders: [
ISODate('2019-05-18T16:09:01.000Z')
]
},
{
_id: 2,
type: 'vanilla',
orderDate: ISODate('2021-01-11T06:31:15.000Z'),
state: 'CA',
price: 12,
quantity: 145,
recentOrders: [
ISODate('2019-05-18T16:09:01.000Z')
]
},
{
_id: 5,
type: 'strawberry',
orderDate: ISODate('2019-01-08T06:12:03.000Z'),
state: 'WA',
price: 43,
quantity: 134,
recentOrders: []
},
{
_id: 3,
type: 'vanilla',
orderDate: ISODate('2020-02-08T13:13:23.000Z'),
state: 'WA',
price: 13,
quantity: 104,
recentOrders: [
ISODate('2019-01-08T06:12:03.000Z')
]
},
{
_id: 1,
type: 'chocolate',
orderDate: ISODate('2021-03-20T11:30:05.000Z'),
state: 'WA',
price: 14,
quantity: 140,
recentOrders: [
ISODate('2019-01-08T06:12:03.000Z'),
ISODate('2020-02-08T13:13:23.000Z')
]
}
]

No exemplo:

  • partitionBy: "$state" partitions the documents in the collection by state. There are partitions for CA and WA.

  • sortBy: { orderDate: 1 } sorts the documents in each partition by orderDate in ascending order (1), so the earliest orderDate is first.

  • output:

    • Define o campo recentOrders para uma array de valores orderDate para os documentos em cada state. Os elementos de array são expandidos com adições aos elementos anteriores na array.

    • Usa $push para retornar uma array de valores orderDate dos documentos em uma janela de faixa.

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

  • $push retorna a array de orderDate valores para os documentos entre o início da partição e os documentos com valores orderDate inclusive em uma faixa do valor orderDate do documento atual menos 10 meses.

O exemplo a seguir usa $setWindowFields com o operador $shift e o estágio $set para comparar campos em uma coleção. Na saída do exemplo, o campo priceComparison mostra o resultado da comparação.

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

No exemplo:

  • partitionBy: "$type" partitions the documents in the collection by type so each type's calculations are kept separate.

  • sortBy: { orderDate: 1 } sorts the documents in each partition by orderDate in ascending order (1).

  • output.previousPrice usa o operador $shift para capturar o price da ordem imediatamente anterior dentro do mesmo ano.

  • $set adiciona um novo campo chamado priceComparison e define o valor desse campo como higher, lower ou same com base na comparação com previousPrice.

Dica

Para obter um exemplo adicional sobre o consumo de energia IOT, consulte o e-book Aggregations práticas do MongoDB.