

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

# $setWindowFields
<a name="setWindowFields"></a>

バージョン 8.0.2 の新機能。

Amazon DocumentDB の`$setWindowFields`ステージは、パーティション内のドキュメント (*ウィンドウ*) の指定されたスパンに対してオペレーションを実行し、選択したウィンドウ演算子に基づいて結果を返します。ステージは入力ドキュメントをパーティションにグループ化し、オプションでソートし、ドキュメントごとに周囲のドキュメントのウィンドウで 1 つ以上の出力フィールドを計算します。

**[Syntax]** (構文)

```
{
  $setWindowFields: {
    partitionBy: <expression>,
    sortBy: { <sortField1>: <sortOrder>, ... },
    output: {
      <outputField1>: {
        <windowOperator>: <expression>,
        window: {
          documents: [ <lowerBound>, <upperBound> ],
          range: [ <lowerBound>, <upperBound> ],
          unit: <time unit>
        }
      },
      ...
    }
  }
}
```

パラメータ****
+ `partitionBy`: オプション。ドキュメントをパーティションにグループ化するために使用される単一の式。これは、フィールドパス ( など`"$state"`) または別の式にすることができます。省略すると、すべての入力ドキュメントは 1 つのパーティションに属します。
+ `sortBy`: オプション。各パーティションのドキュメントをソートするフィールドを`{ <field>: 1 }`昇順または`{ <field>: -1 }`降順で指定するドキュメント。ドキュメントベースまたは範囲ベースのウィンドウ境界を使用する場合、およびランク付け演算子のいずれかを使用する場合、 `sortBy`が必要です。
+ `output`: 必須。各ドキュメントに追加するフィールドを指定するドキュメント。複数の出力フィールドを指定できますが、各出力フィールドには、ウィンドウの境界を定義するウィンドウ演算子、引数、およびオプションの`window`ドキュメントが 1 つだけ含まれます`{ <field>: { <windowOperator>: <expression>, window: { ... } } }`。

## ウィンドウの境界
<a name="setWindowFields-bounds"></a>

各`output`フィールド内では、オプションで`window`ドキュメントを使用してウィンドウの境界を定義できます。ウィンドウは、ドキュメントの位置または値の範囲によって定義できます。
+ `documents`: ウィンドウを、現在のドキュメントの前後のドキュメントの数として 形式で指定します`[ <lowerBound>, <upperBound> ]`。各境界は整数オフセット (例: `-1` または `2`)、またはキーワードの 1 つ `"unbounded"`および です`"current"`。 は、下限として使用する場合はパーティションの先頭に、上限として使用する場合はパーティションの末尾にウィンドウ`"unbounded"`を拡張します。 は現在のドキュメント`"current"`を意味します。両方の境界が `sortBy`でない限り、`documents`ウィンドウには が必要です`"unbounded"`。
+ `range`: ウィンドウを現在のドキュメントに対する`sortBy`フィールド値の範囲として 形式で指定します`[ <lowerBound>, <upperBound> ]`。各バインドは、現在のドキュメント`sortBy`の値、または`"unbounded"`キーワードに追加された数値です。`range` ウィンドウには 1 つの昇順`sortBy`フィールドのみが必要で、`"current"`キーワードを受け入れません。
+ `unit`: オプション。とともに使用`range`して、数値ウィンドウの境界を、`sortBy`フィールドが日付値を保持する期間として解釈します。Amazon DocumentDB は、、`"year"`、、`"quarter"``"month"`、`"week"`、、`"day"`、`"hour"``"minute"``"second"`および の単位をサポートしています`"millisecond"`。`unit` を指定する場合、`range`境界は整数である必要があります。

`window` ドキュメントを省略すると、デフォルトのウィンドウは で`documents: ["unbounded", "unbounded"]`、パーティション全体に及びます。

**注記**  
日付の値を超える`range`ウィンドウを使用する場合は、カレンダーに依存する長さがあいまいなウィンドウ境界を生成する可能性がある `"month"`、`"quarter"`、または ではなく`"year"`、 `"day"` (またはそれより小さい) `unit`などの固定期間を使用することをお勧めします。

## サポートされているウィンドウ演算子
<a name="setWindowFields-operators"></a>

Amazon DocumentDB は、`$setWindowFields`ステージの `output`フィールドで次の 26 個のウィンドウ演算子をサポートしています。
+ `$sum`
+ `$avg`
+ `$count`
+ `$push`
+ `$addToSet`
+ `$stdDevPop`
+ `$stdDevSamp`
+ `$covariancePop`
+ `$covarianceSamp`
+ `$first`
+ `$last`
+ `$firstN`
+ `$lastN`
+ `$top`
+ `$bottom`
+ `$topN`
+ `$bottomN`
+ `$min`
+ `$minN`
+ `$max`
+ `$maxN`
+ `$median`
+ `$percentile`
+ `$rank`
+ `$denseRank`
+ `$documentNumber`

**注記**  
`$rand` 演算子は、`$setWindowFields`ステージのウィンドウ演算子内ではサポートされていません。

**空のウィンドウ**

ウィンドウにドキュメントが含まれていない場合 (範囲の値がない`range`ウィンドウなど）、結果は演算子によって異なります。 `$count` および は `0`、`$push`、、`$addToSet`、`$firstN`、`$lastN``$minN`、 `$maxN``$sum`を返し`$topN`、空の配列`$bottomN`を返します。 `$percentile` は`null`値の配列を返します (リクエストされたパーセンタイルごとに 1 つ）。他のすべての演算子は を返します`null`。

## 例 (MongoDB シェル)
<a name="setWindowFields-examples"></a>

次の例では`region`、ドキュメントを でパーティション化し、各パーティションを でソートし`day`、パーティションの開始`revenue`から現在のドキュメントまでの の累計を計算します。

**サンプルドキュメントを作成する**

```
db.sales.insertMany([
  { _id: 1, region: "east", day: 1, revenue: 100 },
  { _id: 2, region: "east", day: 2, revenue: 150 },
  { _id: 3, region: "east", day: 3, revenue: 120 },
  { _id: 4, region: "west", day: 1, revenue: 200 },
  { _id: 5, region: "west", day: 2, revenue: 180 }
]);
```

**クエリの例**

```
db.sales.aggregate([
  {
    $setWindowFields: {
      partitionBy: "$region",
      sortBy: { day: 1 },
      output: {
        runningRevenue: {
          $sum: "$revenue",
          window: { documents: ["unbounded", "current"] }
        }
      }
    }
  }
]);
```

**出力**

```
[
  { "_id": 1, "region": "east", "day": 1, "revenue": 100, "runningRevenue": 100 },
  { "_id": 2, "region": "east", "day": 2, "revenue": 150, "runningRevenue": 250 },
  { "_id": 3, "region": "east", "day": 3, "revenue": 120, "runningRevenue": 370 },
  { "_id": 4, "region": "west", "day": 1, "revenue": 200, "runningRevenue": 200 },
  { "_id": 5, "region": "west", "day": 2, "revenue": 180, "runningRevenue": 380 }
]
```

各ドキュメントは`runningRevenue`、現在のドキュメントまでのパーティション`revenue`内の の累積合計である で拡張されます。

## コードの例
<a name="setWindowFields-code"></a>

`$setWindowFields` ステージを使用するためのコード例を表示するには、使用する言語のタブを選択します。

------
#### [ Node.js ]

```
const { MongoClient } = require('mongodb');

async function example() {
  const client = new MongoClient('mongodb://<username>:<password>@<cluster-endpoint>:27017/?tls=true&tlsCAFile=global-bundle.pem&replicaSet=rs0&readPreference=secondaryPreferred&retryWrites=false');

  try {
    await client.connect();
    const db = client.db('test');
    const sales = db.collection('sales');

    await sales.insertMany([
      { _id: 1, region: "east", day: 1, revenue: 100 },
      { _id: 2, region: "east", day: 2, revenue: 150 },
      { _id: 3, region: "east", day: 3, revenue: 120 },
      { _id: 4, region: "west", day: 1, revenue: 200 },
      { _id: 5, region: "west", day: 2, revenue: 180 }
    ]);

    const result = await sales.aggregate([
      {
        $setWindowFields: {
          partitionBy: "$region",
          sortBy: { day: 1 },
          output: {
            runningRevenue: {
              $sum: "$revenue",
              window: { documents: ["unbounded", "current"] }
            }
          }
        }
      }
    ]).toArray();

    console.log(result);
  } finally {
    await client.close();
  }
}

example();
```

------
#### [ Python ]

```
from pymongo import MongoClient

def example():
    client = MongoClient('mongodb://<username>:<password>@<cluster-endpoint>:27017/?tls=true&tlsCAFile=global-bundle.pem&replicaSet=rs0&readPreference=secondaryPreferred&retryWrites=false')

    try:
        db = client['test']
        sales = db['sales']

        sales.insert_many([
            { '_id': 1, 'region': 'east', 'day': 1, 'revenue': 100 },
            { '_id': 2, 'region': 'east', 'day': 2, 'revenue': 150 },
            { '_id': 3, 'region': 'east', 'day': 3, 'revenue': 120 },
            { '_id': 4, 'region': 'west', 'day': 1, 'revenue': 200 },
            { '_id': 5, 'region': 'west', 'day': 2, 'revenue': 180 }
        ])

        result = list(sales.aggregate([
            {
                '$setWindowFields': {
                    'partitionBy': '$region',
                    'sortBy': { 'day': 1 },
                    'output': {
                        'runningRevenue': {
                            '$sum': '$revenue',
                            'window': { 'documents': ['unbounded', 'current'] }
                        }
                    }
                }
            }
        ]))

        print(result)
    finally:
        client.close()

example()
```

------