View a markdown version of this page

$set WindowFields - Amazon DocumentDB

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

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

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 ou2), 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 estdocuments: ["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

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'$randopé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)

L'exemple suivant partitionne les documents parregion, 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

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()