

Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.

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

Nouveau depuis la version 8.0.2.

Le `$setWindowFields` stage d'Amazon DocumentDB effectue des opérations sur une plage spécifiée de documents (une * fenêtre*) dans une partition et renvoie les résultats en fonction de l'opérateur de fenêtre choisi. L'étape regroupe les documents d'entrée en partitions, les trie éventuellement et, pour chaque document, calcule un ou plusieurs champs de sortie sur une fenêtre de documents environnants.

**Syntaxe**

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

**Paramètres**
+ `partitionBy` : facultatif. Expression unique utilisée pour regrouper les documents en partitions. Il peut s'agir d'un chemin de champ (par exemple`"$state"`) ou d'une autre expression. En cas d'omission, tous les documents d'entrée appartiennent à une seule partition.
+ `sortBy` : facultatif. Document qui spécifie le ou les champs selon lesquels trier les documents de chaque partition, par ordre croissant ou `{ <field>: -1 }` décroissant. `{ <field>: 1 }` A `sortBy` est obligatoire lorsque vous utilisez des limites de fenêtre basées sur un document ou une plage, et lorsque vous utilisez l'un des opérateurs de classement.
+ `output` : obligatoire. Document qui spécifie les champs à ajouter à chaque document. Vous pouvez spécifier plusieurs champs de sortie, mais chaque champ de sortie prend exactement un opérateur de fenêtre, son argument et un `window` document facultatif qui définit les limites de la fenêtre :`{ <field>: { <windowOperator>: <expression>, window: { ... } } }`.

## Limites des fenêtres
<a name="setWindowFields-bounds"></a>

Dans chaque `output` champ, vous pouvez éventuellement définir les limites de la fenêtre avec un `window` document. Une fenêtre peut être définie par la position du document ou par une plage de valeurs.
+ `documents`: Spécifie la fenêtre sous la forme d'un certain nombre de documents avant et après le document actuel, dans le formulaire`[ <lowerBound>, <upperBound> ]`. Chaque limite est un décalage d'entier (par exemple, `-1` ou`2`), ou l'un des mots-clés `"unbounded"` et`"current"`. `"unbounded"`étend la fenêtre jusqu'au début de la partition lorsqu'elle est utilisée comme limite inférieure, ou jusqu'à la fin de la partition lorsqu'elle est utilisée comme limite supérieure. `"current"`désigne le document en cours. Une `documents` fenêtre nécessite un, `sortBy` sauf si les deux limites le sont`"unbounded"`.
+ `range`: Spécifie la fenêtre sous la forme d'une plage de valeurs de `sortBy` champs relatives au document actuel, dans le formulaire`[ <lowerBound>, <upperBound> ]`. Chaque limite est un numéro qui est ajouté à la `sortBy` valeur du document en cours, ou au `"unbounded"` mot clé. Une `range` fenêtre nécessite exactement un `sortBy` champ croissant et n'accepte pas le `"current"` mot clé.
+ `unit` : facultatif. Utilisé avec `range` pour interpréter les limites de la fenêtre numérique comme une période pendant laquelle le `sortBy` champ contient des valeurs de date. Amazon DocumentDB prend en charge les unités suivantes : `"year"` `"quarter"``"month"`,`"week"`,`"day"`,`"hour"`, `"minute"``"second"`, et`"millisecond"`. Quand `unit` est spécifié, les `range` limites doivent être des entiers.

Lorsque le `window` document est omis, la fenêtre par défaut est`documents: ["unbounded", "unbounded"]`, qui couvre la totalité de la partition.

**Note**  
Lorsque vous utilisez une `range` fenêtre sur des valeurs de date, nous vous recommandons d'utiliser une durée fixe `unit` telle que `"day"` (ou inférieure) plutôt que`"month"`, ou `"quarter"``"year"`, dont les longueurs dépendant du calendrier peuvent produire des limites de fenêtre ambiguës.

## Opérateurs de fenêtres pris en charge
<a name="setWindowFields-operators"></a>

Amazon DocumentDB prend en charge les 26 opérateurs de fenêtre suivants dans le `output` champ de la `$setWindowFields` scène :
+ `$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`

**Note**  
L'`$rand`opérateur n'est pas pris en charge dans un opérateur de fenêtre de la `$setWindowFields` scène.

**Fenêtres vides **

Lorsqu'une fenêtre ne contient aucun document (par exemple, une `range` fenêtre sans valeurs dans la plage), le résultat dépend de l'opérateur : `$count` et `$sum` renvoie `0` ;`$push`,`$addToSet`,`$firstN`, `$lastN` `$minN` `$maxN``$topN`, et renvoie un tableau vide ; `$bottomN` `$percentile` renvoie un tableau de `null` valeurs (une par centile demandé) ; tous les autres opérateurs renvoient. `null`

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

L'exemple suivant partitionne les documents par`region`, trie chaque partition par `day` et calcule un total cumulé `revenue` entre le début de la partition et le document actuel.

**Créez des exemples de documents **

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

**Exemple de requête **

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

**Sortie**

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

Chaque document est augmenté `runningRevenue` de `revenue` la somme cumulée entre sa partition et le document actuel inclus.

## Exemples de code
<a name="setWindowFields-code"></a>

Pour afficher un exemple de code permettant d'utiliser la `$setWindowFields` scène, choisissez l'onglet correspondant à la langue que vous souhaitez utiliser :

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

------