AI エージェント向け: ドキュメントインデックスは https://www.mongodb.com/ja-jp/docs/llms.txt で利用できます。すべてのページの markdown バージョンは、いずれかの URL パスに .md を追加することで利用できます。
Docs Menu

$setWindowFields(集計ステージ)

$setWindowFields

バージョン 5.0 の新機能。

コレクション内の指定されたドキュメント範囲(ウィンドウと呼ばれる)に対して操作を実行し、選択したウィンドウ演算子 に基づいて結果を返します。

例、$setWindowFields ステージを使用して以下を出力できます。

  • コレクション内の 2 つのドキュメント間の売上の差

  • 売上ランキング

  • 累計販売合計

  • データを外部データベースにエクスポートせずに、複雑な時系列情報の分析

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

$setWindowFieldsステージは、次のフィールドを持つドキュメントを取得します。

フィールド
必要性
説明

任意

ドキュメントをグループ化する式を指定します。 ステージでは、ドキュメントのグループはパーティションと呼ばれます。デフォルトでは、コレクション全体に対して 1$setWindowFields つのパーティションです。

一部の演算子に必要です(「制限事項」を参照してください)

パーティション内のドキュメントを並べ替えるフィールドを指定します。$sort ステージと同じ構文を使用します。デフォルトではソートされません。

必須

$setWindowFieldsステージによって返される出力内のドキュメントに追加するフィールドを指定します。各フィールドには、ウィンドウオペレーターによって返された結果が設定されます。

フィールドにドットを含めて、埋め込みドキュメントフィールドと配列フィールドを指定できます。 ステージの埋め込みドキュメントドット表記のセマンティクスは、$setWindowFields ステージおよび$addFields $setステージと同じです。埋め込みドキュメント$addFields の例と埋め込みドキュメント$set の例 を参照してください。

任意

ウィンドウの境界とパラメータを指定します。ウィンドウの境界は包括的です。デフォルトは、パーティション内のすべてのドキュメントが含まれる無制限のウィンドウです。

ドキュメントまたは範囲ウィンドウのいずれかを指定します。

任意

コレクションから読み取られた現在のドキュメントの位置を基準にして下限と上限が指定されるウィンドウ。

ウィンドウの境界は、下限と上限の文字列または整数を含む 2 つの要素の配列を使用して指定されます。次を使用します。

  • 出力内の現在のドキュメント位置の "current" 文字列。

  • パーティション内の最初または最後のドキュメント位置を表す "unbounded" 文字列。

  • 現在のドキュメントに対する相対的な位置を表す整数。現在のドキュメントの前の位置には負の整数を使用します。現在のドキュメントの後の位置には正の整数を使用します。0 は現在のドキュメントの位置です。

「 ドキュメント ウィンドウの例 」を参照してください。

任意

現在のドキュメントの sortBy フィールドに基づく値の範囲を使用して下限と上限が定義されるウィンドウ。

ウィンドウの境界は、下限と上限の文字列または数値を含む 2 つの要素の配列を使用して指定されます。次を使用します。

  • 出力内の現在のドキュメント位置の "current" 文字列。

  • パーティション内の最初または最後のドキュメント位置を表す "unbounded" 文字列。

  • 現在のドキュメントの sortBy フィールドの値に追加する数値。sortBy フィールドの値が下限と上限の範囲内にある場合、ドキュメントはウィンドウ内にあります。

範囲ウィンドウの例」を参照してください。

任意

時間の範囲ウィンドウ境界の単位を指定します。次のいずれかの文字列に設定できます。

  • "year"

  • "quarter"

  • "month"

  • "week"

  • "day"

  • "hour"

  • "minute"

  • "second"

  • "millisecond"

省略した場合は、デフォルトの数値範囲ウィンドウ境界が使用されます。

時間の範囲ウィンドウの例」を参照してください。

Tip

$setWindowFieldsステージは、既存のドキュメントに新しいフィールドを追加します。集計操作には 1 つ以上の$setWindowFields ステージを含めることができます。

MongoDB5.3 以降では、トランザクションと$setWindowFields 読み取り保証 "snapshot"(read concern)で ステージを使用できます。

$setWindowFields ステージでは、返されるドキュメントの順序は保証されません。

これらの演算子は$setWindowFields ステージで使用できます。

バージョン8.3の新機能。

$setWindowsFields操作で explain を実行すると、出力には、使用中の追跡メモリの最大バイト数を含む peakTrackedMemBytesフィールドが含まれます。詳しくは、explain.executionStats.peakTrackedMemBytes を参照してください。

$setWindowFieldsステージの制限:

  • MongoDB5.3 より前では、$setWindowFields ステージは使用できません。

  • sortBy は次の場合に必要です。

  • 範囲ウィンドウでは、すべての sortBy 値が数値である必要があります。

  • 時間範囲Windows 、すべてのsortBy値が日付である必要があります。

  • 範囲ウィンドウと時間範囲ウィンドウには sortBy フィールドを 1 つだけ含めることができ、並べ替えは昇順でなければなりません。

  • ドキュメントウィンドウと範囲ウィンドウの両方を指定することはできません。

  • これらの演算子は暗黙的なウィンドウを使用し、ウィンドウオプションを指定するとエラーを返します。

  • 範囲 ウィンドウの場合、指定された範囲内の数値のみがウィンドウに含まれます。欠落値、未定義値、null 値は除外されます。

  • 時間範囲ウィンドウの場合。

    • ウィンドウには日付と時刻の種類のみが含まれます。

    • 数値境界値は整数である必要があります。たとえば、境界として 2 時間を使用できますが、1.5 時間は使用できません。

  • 空のウィンドウまたは互換性のない値を持つウィンドウ(例: 文字列で $sum を使用)の場合、返される値は演算子によって異なります。

    • $count および $sum の場合、返される値は 0 です。

    • $addToSet および $push の場合、返される値は空の配列になります。

    • その他のすべての演算子の場合、返される値は null です。

カリフォルニア州(CA)とワシントン州(WA)のケーキ販売を含む cakeSales コレクションを作成します。

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

次の例では cakeSales コレクションを使用します。

この例では、 $setWindowFieldsquantityのドキュメントウィンドウを使用して、各 の累計のケーキ売上state を出力します。

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

この例では、次のことが行われます。

  • partitionBy: "$state" はコレクション内のドキュメントをstate で 分割 します。CA WAと 用のパーティションがあります。

  • sortBy: { orderDate: 1 } は各パーティション内のドキュメントをorderDate で昇順(1 )にソートするため、最も近いorderDate が先頭になります。

  • output:

    • cumulativeQuantityForState フィールドを各 state の累積 quantity に設定します。これは、パーティション内の前の値に連続して追加されることによって増加します。

    • ドキュメントウィンドウで実行される 演算子を使用して、累積quantity $sumを計算します。

      unboundedウィンドウ には、 下限とcurrent ドキュメントの間のドキュメントが含まれています。つまり、$sum quantityは、パーティションの先頭から現在のドキュメントまでのドキュメントの累積 を返します。

この出力例では、CAWA の累積 quantitycumulativeQuantityForState フィールドに表示されます。

{ "_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 }

この例では、 のドキュメントウィンドウを使用して、 $setWindowFieldsquantityの各$year の累計のケーキ売上orderDate を出力します。

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

この例では、次のことが行われます。

  • partitionBy: { $year: "$orderDate" } コレクション内のドキュメントを$yearorderDate で 分割 します。2019 2020、 、2021 のパーティションがあります。

  • sortBy: { orderDate: 1 } は各パーティション内のドキュメントをorderDate で昇順(1 )にソートするため、最も近いorderDate が先頭になります。

  • output:

    • cumulativeQuantityForYear フィールドを各年の累積 quantity に設定します。これは、パーティション内の前の値に連続して追加されることによって増加します。

    • ドキュメントウィンドウで実行される 演算子を使用して、累積quantity $sumを計算します。

      unboundedウィンドウ には、 下限とcurrent ドキュメントの間のドキュメントが含まれています。つまり、$sum quantityは、パーティションの先頭から現在のドキュメントまでのドキュメントの累積 を返します。

この出力例では、各年の累積 quantitycumulativeQuantityForYear フィールドに表示されます。

{ "_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 }

この例では、 のドキュメントウィンドウを使用して、ケーキの売上 $setWindowFieldsの移動平均を出力します。quantity

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

この例では、次のことが行われます。

  • partitionBy: "$orderDate" コレクション内のドキュメントを$yearorderDate で 分割 します。2019 2020、 、2021 のパーティションがあります。

  • sortBy: { orderDate: 1 } は各パーティション内のドキュメントをorderDate で昇順(1 )にソートするため、最も近いorderDate が先頭になります。

  • output:

    • averageQuantity フィールドを各年の移動平均 quantity に設定します。

    • ドキュメントウィンドウで実行される 演算子を使用して、移動平均quantity $avgを計算します。

      ウィンドウには から-1 0の間のドキュメントが含まれています。つまり、$avg quantityは、パーティション内の現在のドキュメントの前のドキュメント(-1 )と現在のドキュメント(0 )の間の移動平均 を返します。

この出力例では、移動平均 quantityaverageQuantity フィールドに表示されます。

{ "_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 }

この例では、 のドキュメントウィンドウを使用して、 $setWindowFieldsquantityの各 の累計と最大のケーキ売上$year 値を出力します。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" ]
}
}
}
}
}
] )

この例では、次のことが行われます。

  • partitionBy: "$orderDate" コレクション内のドキュメントを$yearorderDate で 分割 します。2019 2020、 、2021 のパーティションがあります。

  • sortBy: { orderDate: 1 } は各パーティション内のドキュメントをorderDate で昇順(1 )にソートするため、最も近いorderDate が先頭になります。

  • output:

    • cumulativeQuantityForYear フィールドを各年の累積 quantity に設定します。

    • ドキュメントウィンドウで実行される 演算子を使用して、累積quantity $sumを計算します。

      unboundedウィンドウ には、 下限とcurrent ドキュメントの間のドキュメントが含まれています。つまり、$sum は、パーティションの最初から現在のドキュメントまで、ドキュメントの累積数量を返します。

    • maximumQuantityForYear フィールドを各年の最大値 quantity に設定します。

    • ドキュメントウィンドウで実行される 演算子を使用して、すべてのドキュメントの最大quantity $maxを計算します。

      ウィンドウ には、unbounded upper下限から の上限の間のドキュメントが含まれています。つまり、$max はパーティション内のドキュメントの最大量を返します。

この出力例では、累積 quantitycumulativeQuantityForYear フィールドに表示され、最大値 quantitymaximumQuantityForYear フィールドに表示されます。

{ "_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 }

この例では、 $setWindowFieldsquantity10の範囲ウィンドウを使用して、現在のドキュメントのprice 値のプラスマイナス ドル以内の注文で販売されたケーキの 値の合計を返します。

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

この例では、次のことが行われます。

  • partitionBy: "$state" はコレクション内のドキュメントをstate で 分割 します。CA WAと 用のパーティションがあります。

  • sortBy: { price: 1 } は各パーティション内のドキュメントをprice で昇順(1 )にソートするため、最低のprice が先頭になります。

  • output quantityFromSimilarOrders フィールドを、範囲 ウィンドウ内のドキュメントの quantity 値の合計に設定します。

    • ウィンドウ には、下限値-10 と上限値10 の間のドキュメントが含まれています。範囲はこの値を含みます。

    • $sum は、現在のドキュメントの price の値のプラスマイナス 10 ドルの範囲に含まれる quantity 個の値の合計を返します。

この出力例では、ウィンドウ内のドキュメントの quantity 値の合計が 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 }

次の例では、 $setWindowFieldsの正の上限時間範囲単位を持つウィンドウを使用します。パイプラインは、指定された時間範囲に一致する各orderDatestate 値の配列を出力します。

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

この例では、次のことが行われます。

  • partitionBy: "$state" はコレクション内のドキュメントをstate で 分割 します。CA WAと 用のパーティションがあります。

  • sortBy: { orderDate: 1 } は各パーティション内のドキュメントをorderDate で昇順(1 )にソートするため、最も近いorderDate が先頭になります。

  • output:

    • state 内のドキュメントの orderDate 値の配列に recentOrdersフィールドを設定します。配列要素は、配列内の前の要素に追加されて拡張されます。

    • $push を使用して、範囲ウィンドウのドキュメントから orderDate の値の配列を返します。

  • ウィンドウ には、時間範囲 単位 を使用して、 unbounded下限と1010 (現在のドキュメントの 値から か月後)の間のドキュメントが含まれます。orderDate

  • $push は、パーティションの先頭から、現在のドキュメントの orderDate 値に 10 か月を加えた範囲に含まれる orderDate 値を持つドキュメントまでの間のドキュメントの orderDate 値の配列を返します。

この出力例では、CAWAorderDate 値の配列が recentOrders フィールドに表示されます。

{ "_id" : 4, "type" : "strawberry", "orderDate" : ISODate("2019-05-18T16:09:01Z"),
"state" : "CA", "price" : 41, "quantity" : 162,
"recentOrders" : [ ISODate("2019-05-18T16:09:01Z") ] }
{ "_id" : 0, "type" : "chocolate", "orderDate" : ISODate("2020-05-18T14:10:30Z"),
"state" : "CA", "price" : 13, "quantity" : 120,
"recentOrders" : [ ISODate("2019-05-18T16:09:01Z"), ISODate("2020-05-18T14:10:30Z"), ISODate("2021-01-11T06:31:15Z") ] }
{ "_id" : 2, "type" : "vanilla", "orderDate" : ISODate("2021-01-11T06:31:15Z"),
"state" : "CA", "price" : 12, "quantity" : 145,
"recentOrders" : [ ISODate("2019-05-18T16:09:01Z"), ISODate("2020-05-18T14:10:30Z"), ISODate("2021-01-11T06:31:15Z") ] }
{ "_id" : 5, "type" : "strawberry", "orderDate" : ISODate("2019-01-08T06:12:03Z"),
"state" : "WA", "price" : 43, "quantity" : 134,
"recentOrders" : [ ISODate("2019-01-08T06:12:03Z") ] }
{ "_id" : 3, "type" : "vanilla", "orderDate" : ISODate("2020-02-08T13:13:23Z"),
"state" : "WA", "price" : 13, "quantity" : 104,
"recentOrders" : [ ISODate("2019-01-08T06:12:03Z"), ISODate("2020-02-08T13:13:23Z") ] }
{ "_id" : 1, "type" : "chocolate", "orderDate" : ISODate("2021-03-20T11:30:05Z"),
"state" : "WA", "price" : 14, "quantity" : 140,
"recentOrders" : [ ISODate("2019-01-08T06:12:03Z"), ISODate("2020-02-08T13:13:23Z"), ISODate("2021-03-20T11:30:05Z") ] }

次の例では、 $setWindowFieldsの負の上限時間範囲単位を持つウィンドウを使用します。パイプラインは、指定された時間範囲に一致する各orderDatestate 値の配列を出力します。

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

この例では、次のことが行われます。

  • partitionBy: "$state" はコレクション内のドキュメントをstate で 分割 します。CA WAと 用のパーティションがあります。

  • sortBy: { orderDate: 1 } は各パーティション内のドキュメントをorderDate で昇順(1 )にソートするため、最も近いorderDate が先頭になります。

  • output:

    • state 内のドキュメントの orderDate 値の配列に recentOrdersフィールドを設定します。配列要素は、配列内の前の要素に追加されて拡張されます。

    • $push を使用して、範囲ウィンドウのドキュメントから orderDate の値の配列を返します。

  • ウィンドウ には、時間範囲 単位 を使用して、 unbounded下限と-1010 (現在のドキュメントの 値の前の か月前)に設定されたの間のドキュメントが含まれます。orderDate

  • $push は、パーティションの先頭から、現在のドキュメントの orderDate 値から 10 か月を引いた範囲に含まれる orderDate 値を持つドキュメントまでの間のドキュメントの orderDate 値の配列を返します。

この出力例では、CAWAorderDate 値の配列が recentOrders フィールドに表示されます。

{ "_id" : 4, "type" : "strawberry", "orderDate" : ISODate("2019-05-18T16:09:01Z"),
"state" : "CA", "price" : 41, "quantity" : 162,
"recentOrders" : [ ] }
{ "_id" : 0, "type" : "chocolate", "orderDate" : ISODate("2020-05-18T14:10:30Z"),
"state" : "CA", "price" : 13, "quantity" : 120,
"recentOrders" : [ ISODate("2019-05-18T16:09:01Z") ] }
{ "_id" : 2, "type" : "vanilla", "orderDate" : ISODate("2021-01-11T06:31:15Z"),
"state" : "CA", "price" : 12, "quantity" : 145,
"recentOrders" : [ ISODate("2019-05-18T16:09:01Z") ] }
{ "_id" : 5, "type" : "strawberry", "orderDate" : ISODate("2019-01-08T06:12:03Z"),
"state" : "WA", "price" : 43, "quantity" : 134,
"recentOrders" : [ ] }
{ "_id" : 3, "type" : "vanilla", "orderDate" : ISODate("2020-02-08T13:13:23Z"),
"state" : "WA", "price" : 13, "quantity" : 104,
"recentOrders" : [ ISODate("2019-01-08T06:12:03Z") ] }
{ "_id" : 1, "type" : "chocolate", "orderDate" : ISODate("2021-03-20T11:30:05Z"),
"state" : "WA", "price" : 14, "quantity" : 140,
"recentOrders" : [ ISODate("2019-01-08T06:12:03Z"), ISODate("2020-02-08T13:13:23Z") ] }

次の例では、$setWindowFields$shift 演算子と $set ステージとともに使用して、コレクション内のフィールドを比較しています。

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

この例では、次のことが行われます。

  • partitionBy: "$type" はコレクション内のドキュメントを で 分割type するため、各タイプの計算は別々に保持されます。

  • sortBy: { orderDate: 1 } 各パーティション内のドキュメントをorderDate で昇順(1 )でソートします。

  • output.previousPrice $shiftは、price 演算子を使用して、同じ年内の直前の順序から を取得します。

  • $setpriceComparison という新しいフィールドを追加し、previousPrice との比較に基づいてそのフィールドの値を higherlower、または same に設定します。

この出力例では、比較の結果が 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'
}
]

次の WeatherMeasurementクラスは、気象測定値のコレクション内のドキュメントを表します。

[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; }
}

MongoDB .NET/ C#ドライバーを使用して$setWindowFields ステージを集計パイプラインに追加するには、 PipelineDefinitionオブジェクトで UnionWith() メソッドを呼び出します。

次の例では、Rainfall フィールドと Temperature フィールドを使用して、各地域の過去 1 か月の累積降量、移動平均温度、中央値、90 パーセンタイル降量を計算するパイプラインステージを作成します。

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] }

このページの Node.js の例では、Atlas サンプルデータセットsample_weatherdata.data コレクションを使用します。無料の MongoDB Atlas クラスターを作成し、サンプルデータセットをロードする方法を学ぶには、MongoDB Node.js ドライバーのドキュメント「使用開始」をご覧ください。

MongoDB Node.jsドライバーを使用して $setWindowFields ステージを集計パイプラインに追加するには、パイプラインオブジェクトで $setWindowFields 演算子を使用します。

次の例では、過去1か月間におけるcallLettersの各一意の値に対して、平均airTemperature.valueと合計waveMeasurement.waves.heightを計算するパイプラインステージを作成します。次に、この例は集計パイプラインを実行します。

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

IoT 電力消費に関する追加の例については、電子書籍『 MongoDB の実用的な集計 』を参照してください。