

Le traduzioni sono generate tramite traduzione automatica. In caso di conflitto tra il contenuto di una traduzione e la versione originale in Inglese, quest'ultima prevarrà.

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

Nuovo dalla versione 8.0.2.

La `$setWindowFields` fase di Amazon DocumentDB esegue operazioni su un determinato intervallo di documenti (una * finestra*) in una partizione e restituisce i risultati in base all'operatore di finestra scelto. La fase raggruppa i documenti di input in partizioni, facoltativamente li ordina e per ogni documento calcola uno o più campi di output su una finestra di documenti circostanti.

**Sintassi**

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

**Parametri**
+ `partitionBy`: facoltativo. Una singola espressione utilizzata per raggruppare i documenti in partizioni. Può essere un percorso di campo (ad esempio`"$state"`) o un'altra espressione. Se omesso, tutti i documenti di input appartengono a una singola partizione.
+ `sortBy`: facoltativo. Un documento che specifica il campo o i campi in base ai quali ordinare i documenti di ciascuna partizione, in ordine crescente o decrescente. `{ <field>: 1 }` `{ <field>: -1 }` A `sortBy` è obbligatorio quando si utilizzano limiti di finestra basati su documenti o intervalli e quando si utilizza uno degli operatori di classificazione.
+ `output`: richiesto. Un documento che specifica i campi da aggiungere a ciascun documento. È possibile specificare più campi di output, ma ogni campo di output richiede esattamente un operatore di finestra, il relativo argomento e un `window` documento opzionale che definisce i limiti della finestra:. `{ <field>: { <windowOperator>: <expression>, window: { ... } } }`

## Limiti delle finestre
<a name="setWindowFields-bounds"></a>

All'interno di ogni `output` campo è possibile definire facoltativamente i confini della finestra con un `window` documento. Una finestra può essere definita in base alla posizione del documento o a un intervallo di valori.
+ `documents`: specifica la finestra come numero di documenti prima e dopo il documento corrente, nel modulo`[ <lowerBound>, <upperBound> ]`. Ogni limite è un offset intero (ad esempio, `-1` o`2`) o una delle parole chiave and. `"unbounded"` `"current"` `"unbounded"`estende la finestra all'inizio della partizione se utilizzata come limite inferiore o alla fine della partizione se utilizzata come limite superiore. `"current"`indica il documento corrente. Una `documents` finestra richiede un `sortBy` a meno che non lo siano entrambi i `"unbounded"` limiti.
+ `range`: specifica la finestra come un intervallo di valori di `sortBy` campo relativi al documento corrente, nel modulo. `[ <lowerBound>, <upperBound> ]` Ogni limite è un numero che viene aggiunto al `sortBy` valore del documento corrente o alla `"unbounded"` parola chiave. Una `range` finestra richiede esattamente un `sortBy` campo crescente e non accetta la `"current"` parola chiave.
+ `unit`: facoltativo. Utilizzato con `range` per interpretare i limiti numerici della finestra come un intervallo di tempo in cui il `sortBy` campo contiene valori di data. Amazon DocumentDB supporta le seguenti unità:`"year"`,,`"quarter"`,,`"month"`,`"week"`, `"day"``"hour"`, `"minute"` e. `"second"` `"millisecond"` Quando `unit` è specificato, i `range` limiti devono essere numeri interi.

Quando il `window` documento viene omesso, la finestra predefinita è`documents: ["unbounded", "unbounded"]`, che copre l'intera partizione.

**Nota**  
Quando si utilizza una `range` finestra sui valori di data, si consiglia una durata fissa `unit` come `"day"` (o inferiore) anziché`"month"`, o `"quarter"``"year"`, le cui lunghezze dipendenti dal calendario possono generare limiti ambigui della finestra.

## Operatori di finestra supportati
<a name="setWindowFields-operators"></a>

Amazon DocumentDB supporta i seguenti 26 operatori di finestre nel `output` campo dello `$setWindowFields` stage:
+ `$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`

**Nota**  
L'`$rand`operatore non è supportato all'interno di un operatore di finestra nello `$setWindowFields` stage.

**Finestre vuote **

Quando una finestra non contiene documenti (ad esempio, una `range` finestra senza valori nell'intervallo), il risultato dipende dall'operatore: `$count` and `$sum` return`0`;`$push`,,,`$addToSet`,`$firstN`, `$lastN` `$minN` `$maxN``$topN`, e `$bottomN` restituisce un array vuoto; `$percentile` restituisce un array di `null` valori (uno per percentile richiesto); tutti gli altri operatori restituiscono`null`.

## Esempio (MongoDB Shell)
<a name="setWindowFields-examples"></a>

L'esempio seguente partiziona i documenti in base`region`, ordina ogni partizione in base `day` e calcola un totale progressivo di `revenue` dall'inizio della partizione fino al documento corrente.

**Create documenti di esempio **

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

**Esempio di interrogazione **

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

**Output**

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

Ogni documento è `runningRevenue` arricchito dalla somma cumulativa della `revenue` sua partizione fino al documento corrente incluso.

## Esempi di codice
<a name="setWindowFields-code"></a>

Per visualizzare un esempio di codice per l'utilizzo dello `$setWindowFields` stage, scegli la scheda corrispondente alla lingua che desideri utilizzare:

------
#### [ 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()
```

------