MongoDB Academy · Leçon

Fonctions de fenêtre avec $setWindowFields

Les apprenants calculeront des totaux cumulés, des rangs et des moyennes mobiles sur des partitions ordonnées avec l’étape $setWindowFields.

Leçon 4 sur 413 étapes

Fonctions de fenêtre avec $setWindowFields est une leçon MongoDB Academy gratuite sur CoddyKit. Ceci est la leçon 4 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage MongoDB Academy, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours MongoDB Academy comprend 4 leçons au total.

Que sont les fonctions de fenêtre ?

Les fonctions de fenêtre calculent des valeurs sur un ensemble de documents liés au document actuel — une « fenêtre » — sans les regrouper en un seul groupe comme le fait $group. Elles sont apparues dans SQL (SQL:2003) et ont été ajoutées à MongoDB dans la version 5.0 via l’étape de pipeline $setWindowFields. Parmi leurs utilisations courantes figurent les totaux cumulés, les moyennes mobiles, les classements et les métriques cumulées.

Structure de l’étape $setWindowFields

L’étape $setWindowFields comporte trois clés de configuration principales : partitionBy définit la manière de diviser les documents en fenêtres indépendantes (comme GROUP BY en SQL), sortBy ordonne les documents au sein de chaque partition, et output indique les nouveaux champs à calculer ainsi que leur opérateur de fenêtre et les limites de la fenêtre.

db.dailySales.aggregate([
  {
    $setWindowFields: {
      partitionBy: '$region',        // separate window per region
      sortBy: { saleDate: 1 },       // order by date within each region
      output: {
        runningTotal: {
          $sum: '$amount',
          window: { documents: ['unbounded', 'current'] }
        }
      }
    }
  }
])

Limites de fenêtre fondées sur les documents

Les limites de fenêtre définissent les documents qui contribuent au calcul pour chaque ligne. Les limites fondées sur les documents utilisent la clé documents avec un tableau à deux éléments : la position de début et la position de fin par rapport au document actuel. 'unbounded' signifie « depuis le début (ou jusqu’à la fin) », 'current' désigne le document actuel, et les décalages numériques comme -1 signifient « un document avant ». Modèles courants : ['unbounded', 'current'] pour un total cumulé, et [-1, 1] pour une fenêtre mobile de 3 documents.

// Running total: all documents from the start up to the current row
window: { documents: ['unbounded', 'current'] }

// 3-document moving window: previous, current, and next document
window: { documents: [-1, 1] }

// Cumulative (all documents from start to end)
window: { documents: ['unbounded', 'unbounded'] }

Limites de fenêtre fondées sur une plage

Les limites fondées sur une plage définissent la fenêtre à l’aide de plages de valeurs sur la clé de tri plutôt que de décalages de documents. Cette méthode est particulièrement utile pour les données de séries temporelles lorsque vous voulez obtenir « les 7 derniers jours » plutôt que « les 7 derniers documents ». Utilisez la clé range avec une unité pour les champs de date. Cette méthode gère correctement les données manquantes, lorsque certains jours peuvent être absents.

db.temperatures.aggregate([
  {
    $setWindowFields: {
      partitionBy: '$station',
      sortBy: { readingDate: 1 },
      output: {
        sevenDayAvgTemp: {
          $avg: '$temperature',
          window: {
            range: [-6, 0], // 6 days before up to current day
            unit: 'day'
          }
        }
      }
    }
  }
])

Calculer des totaux cumulés

Un total cumulé (somme cumulative) se calcule en définissant une fenêtre qui s’étend du premier document de la partition jusqu’au document actuel. Lorsque MongoDB traite chaque document dans l’ordre de tri, il ajoute la valeur de ce document à toutes les valeurs précédentes. Cela produit un total croissant dans chaque partition, utile pour le chiffre d’affaires cumulé ou le nombre progressif de téléchargements.

db.transactions.aggregate([
  {
    $setWindowFields: {
      partitionBy: '$accountId',
      sortBy: { date: 1 },
      output: {
        runningBalance: {
          $sum: '$amount',
          window: { documents: ['unbounded', 'current'] }
        }
      }
    }
  },
  { $project: { accountId: 1, date: 1, amount: 1, runningBalance: 1 } }
])

Moyennes mobiles pour lisser les données

Une moyenne mobile atténue les fluctuations à court terme des données de séries temporelles afin de faire ressortir les tendances sous-jacentes. Configurez la fenêtre pour qu’elle couvre un nombre fixe de périodes dans les deux directions, ou uniquement les périodes précédentes pour obtenir une moyenne « glissante ». Les moyennes mobiles sont courantes dans les graphiques financiers, les tableaux de bord de surveillance des performances et l’analyse des capteurs de l’Internet des objets.

db.stockPrices.aggregate([
  {
    $setWindowFields: {
      partitionBy: '$ticker',
      sortBy: { date: 1 },
      output: {
        movingAvg5Day: {
          $avg: '$closePrice',
          window: { documents: [-4, 0] } // current + 4 previous = 5 day average
        },
        movingAvg10Day: {
          $avg: '$closePrice',
          window: { documents: [-9, 0] } // 10-day trailing average
        }
      }
    }
  }
])

Classer avec $rank et $denseRank

L’opérateur $rank attribue un numéro de classement à chaque document de sa partition, selon l’ordre de tri. Les documents ex æquo reçoivent le même rang, et le rang suivant est augmenté en conséquence (1, 2, 2, 4). $denseRank attribue des rangs consécutifs sans saut en cas d’égalité (1, 2, 2, 3). Aucun des deux ne prend de spécification de fenêtre : ils classent toujours l’ensemble de la partition.

db.leaderboard.aggregate([
  {
    $setWindowFields: {
      partitionBy: '$gameId',
      sortBy: { score: -1 }, // highest score = rank 1
      output: {
        rank: { $rank: {} },
        denseRank: { $denseRank: {} }
      }
    }
  },
  { $match: { rank: { $lte: 10 } } } // top 10 per game
])

$documentNumber : numéroter les lignes dans une partition

$documentNumber attribue à chaque document de sa partition un entier séquentiel commençant à 1, selon l’ordre de tri. Contrairement à $rank, il ne répète jamais les nombres : chaque document reçoit un numéro unique. Cela est utile pour la pagination, la numérotation d’une séquence ou lorsque vous devez déterminer quelle ligne d’une partition occupe un document.

db.orders.aggregate([
  {
    $setWindowFields: {
      partitionBy: '$customerId',
      sortBy: { orderDate: 1 },
      output: {
        orderSequence: { $documentNumber: {} } // 1st order, 2nd order, etc.
      }
    }
  },
  // Find customers' 3rd orders
  { $match: { orderSequence: 3 } }
])

$shift : accéder aux documents adjacents

$shift renvoie la valeur d’une expression provenant d’un document situé à un décalage donné par rapport au document actuel dans la partition. Utilisez by: -1 pour accéder à la valeur du document précédent (par exemple, le prix d’hier), by: 1 pour accéder au document suivant, et indiquez une valeur default lorsque le décalage dépasse les limites de la partition.

db.dailyMetrics.aggregate([
  {
    $setWindowFields: {
      partitionBy: '$metricName',
      sortBy: { date: 1 },
      output: {
        previousValue: {
          $shift: {
            output: '$value',
            by: -1,
            default: null
          }
        },
        // Compute day-over-day change using $shift
        dayOverDayChange: {
          $subtract: [
            '$value',
            { $shift: { output: '$value', by: -1, default: '$value' } }
          ]
        }
      }
    }
  }
])

Performances et utilisation des index

$setWindowFields tire parti des index sur les champs de partition et de tri. Un index couvrant à la fois la clé de partition et la clé de tri permet à MongoDB de récupérer efficacement les documents de chaque partition dans l’ordre de tri, sans analyser toute la collection. Sans index, MongoDB doit effectuer le tri en mémoire (dans les limites de allowDiskUse). Pour les collections volumineuses, veillez à ce que vos index correspondent aux spécifications de partition et de tri de vos fonctions de fenêtre.

// For this $setWindowFields:
// partitionBy: '$accountId', sortBy: { date: 1 }
// Create a compound index:
db.transactions.createIndex({ accountId: 1, date: 1 })
// MongoDB can now efficiently scan per-partition in date order

Exemple pratique : rapport des performances commerciales

Un rapport commercial réel peut nécessiter d’enrichir les transactions de chaque commercial avec son total cumulé, son classement au sein de son équipe et le total cumulé de l’équipe, le tout calculé dans un seul pipeline, sans jointures multiples ni calcul côté application. C’est exactement le type de requête analytique pour lequel $setWindowFields a été conçu.

db.sales.aggregate([
  {
    $setWindowFields: {
      partitionBy: '$teamId',
      sortBy: { amount: -1 },
      output: {
        rankInTeam: { $rank: {} },
        runningTeamTotal: {
          $sum: '$amount',
          window: { documents: ['unbounded', 'current'] }
        },
        teamTotal: {
          $sum: '$amount',
          window: { documents: ['unbounded', 'unbounded'] }
        }
      }
    }
  }
])

Vérification rapide

Testez votre compréhension des concepts de MongoDB et des bases de données NoSQL présentés dans cette leçon.

Récapitulatif de la leçon

Dans cette leçon, vous avez appris que $setWindowFields calcule des valeurs sur une fenêtre glissante de documents associés sans les regrouper comme le fait $group, que les limites de fenêtre fondées sur les documents et sur les plages contrôlent les documents qui contribuent à chaque calcul, et que des opérateurs tels que $rank, $denseRank, $documentNumber et $shift permettent d'effectuer des classements, des numérotations et des comparaisons entre lignes. Nous allons maintenant explorer les garanties ACID dans le magasin de documents distribué de MongoDB.

Gratuit pour commencer

Apprends JavaScript avec un tuteur IA — gratuit

Écris et exécute du vrai code dans ton navigateur, obtiens de l'aide instantanée d'un tuteur IA disponible 24h/24, et reprends là où tu t'es arrêté sur le web ou dans l'app.

Cours
30
Leçons
120

Questions Fréquemment Posées

La leçon « Fonctions de fenêtre avec $setWindowFields » est-elle gratuite ?

Oui — le texte complet de « Fonctions de fenêtre avec $setWindowFields » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours MongoDB Academy, passe à CoddyKit PRO. Le cours MongoDB Academy comprend 4 leçons au total.

Qu'est-ce que j'apprendrai dans « Fonctions de fenêtre avec $setWindowFields » ?

Les apprenants calculeront des totaux cumulés, des rangs et des moyennes mobiles sur des partitions ordonnées avec l’étape $setWindowFields. Tu pratiques MongoDB Academy avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.

Dois-je avoir de l'expérience pour commencer MongoDB Academy ?

Aucune expérience préalable n'est requise. MongoDB Academy sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 4 sur 4.

Combien de temps prend la leçon « Fonctions de fenêtre avec $setWindowFields » ?

La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.

Peux-tu écrire et exécuter du code dans cette leçon MongoDB Academy ?

Oui. Chaque leçon MongoDB Academy inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.

Toutes les leçons de ce cours

  1. $sum, $avg, $min, $max : agrégation numérique
  2. $push et $addToSet : construire des tableaux dans les groupes
  3. Accumulateurs $first, $last et $top/$bottom
  4. Fonctions de fenêtre avec $setWindowFields
← Retour à MongoDB Academy