

기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.

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

버전 8.0.2에서 새로 추가되었습니다.

Amazon DocumentDB의 `$setWindowFields` 단계는 파티션의 지정된 문서 범위(*창*)에서 작업을 수행하고 선택한 창 연산자를 기반으로 결과를 반환합니다. 스테이지는 입력 문서를 파티션으로 그룹화하고, 선택적으로 정렬하고, 각 문서에 대해 주변 문서의 창에서 하나 이상의 출력 필드를 계산합니다.

**구문**

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

**파라미터**
+ `partitionBy`: 선택 사항입니다. 문서를 파티션으로 그룹화하는 데 사용되는 단일 표현식입니다. 필드 경로(예: `"$state"`) 또는 다른 표현식일 수 있습니다. 생략하면 모든 입력 문서가 단일 파티션에 속합니다.
+ `sortBy`: 선택 사항입니다. 각 파티션의 문서를 오름`{ <field>: 1 }`차순 또는 `{ <field>: -1 }` 내림차순으로 정렬할 필드를 지정하는 문서입니다. 문서 기반 또는 범위 기반 창 경계를 사용하고 순위 연산자 중 하나를 사용하는 경우가 `sortBy` 필요합니다.
+ `output`: 필수 항목입니다. 각 문서에 추가할 필드를 지정하는 문서입니다. 여러 출력 필드를 지정할 수 있지만 각 출력 필드는 정확히 하나의 창 연산자, 인수 및 창 경계를 정의하는 선택적 `window` 문서를 사용합니다`{ <field>: { <windowOperator>: <expression>, window: { ... } } }`.

## 창 경계
<a name="setWindowFields-bounds"></a>

각 `output` 필드 내에서 선택적으로 `window` 문서로 창 경계를 정의할 수 있습니다. 창은 문서 위치 또는 값 범위에 따라 정의할 수 있습니다.
+ `documents`: 창을 현재 문서 앞뒤의 여러 문서로 형식으로 지정합니다`[ <lowerBound>, <upperBound> ]`. 각 경계는 정수 오프셋(예: `-1` 또는 `2`)이거나 키워드 `"unbounded"` 및 중 하나입니다`"current"`.는 하한으로 사용되는 경우 창을 파티션의 시작으로, 상한으로 사용되는 경우 파티션의 끝으로 `"unbounded"` 확장합니다.는 현재 문서를 `"current"` 의미합니다. 두 경계가 모두가 `sortBy` 아니면 `documents` 창에가 필요합니다`"unbounded"`.
+ `range`: 창을 현재 문서와 관련된 `sortBy` 필드 값의 범위로 형식으로 지정합니다`[ <lowerBound>, <upperBound> ]`. 각 경계는 현재 문서의 `sortBy` 값 또는 `"unbounded"` 키워드에 추가되는 숫자입니다. `range` 창에는 정확히 하나의 오름차순 `sortBy` 필드가 필요하며 `"current"` 키워드를 수락하지 않습니다.
+ `unit`: 선택 사항입니다. `range`와 함께 사용하여 숫자 창 경계를 `sortBy` 필드에 날짜 값이 포함된 시간 범위로 해석합니다. Amazon DocumentDB는 `"year"`, , `"quarter"`, `"month"`, , `"week"`, `"day"``"hour"`, `"second"`및 단위`"minute"`를 지원합니다`"millisecond"`. `unit`를 지정할 때 `range` 경계는 정수여야 합니다.

`window` 문서가 생략되면 기본 기간은 전체 파티션에 걸쳐 `documents: ["unbounded", "unbounded"]`있는 입니다.

**참고**  
`range` 기간 초과 날짜 값을 사용하는 경우 일정에 따라 길이가 모호한 기간 경계를 생성할 수 `"year"`있는 `"month"`, `"quarter"`또는가 아닌 `"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`, `$sum` , `$push`, , `$addToSet`, `$firstN``$lastN`, `$maxN`, , `$minN``$topN`, , ,는 빈 배열을 `$bottomN` 반환하고,는 `null` 값 배열(요청된 백분위수당 하나)을 `$percentile` 반환하며, 다른 모든 연산자는를 반환합니다`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 }
]
```

각 문서는 현재 문서까지 파티션 `revenue` 내의 누적 합계`runningRevenue`인 로 보강됩니다.

## 코드 예제
<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()
```

------