Grouper les données MongoDB

MongoDBBeginner
Pratiquer maintenant

Introduction

Dans ce laboratoire, vous apprendrez les bases de l'agrégation de données dans MongoDB. Vous vous concentrerez sur l'utilisation du pipeline d'agrégation pour regrouper des documents, effectuer des calculs sur les données groupées, puis filtrer, trier et remodeler les résultats. Ces opérations sont essentielles pour l'analyse et le reporting des données dans MongoDB. À la fin de ce laboratoire, vous serez à l'aise avec l'opérateur $group ainsi qu'avec d'autres étapes d'agrégation clés pour extraire des informations significatives de vos données.

Regrouper les documents par un champ

La première étape de l'agrégation de données consiste souvent à regrouper des documents en fonction d'un champ commun. Dans cette étape, vous vous connecterez au shell MongoDB, créerez une nouvelle base de données et une nouvelle collection, puis utiliserez l'opérateur $group pour regrouper les documents par catégorie.

Tout d'abord, ouvrez le shell MongoDB en exécutant la commande suivante dans votre terminal :

mongosh

Une fois dans le shell, vous verrez une invite test>. Passons à une nouvelle base de données appelée salesdb et insérons des données de produits exemples. MongoDB créera automatiquement la base de données et la collection lorsque vous y insérerez des données pour la première fois.

Copiez et collez les commandes suivantes dans le shell mongosh :

use salesdb
db.products.insertMany([
  { category: "Electronics", brand: "Apple", price: 1200 },
  { category: "Electronics", brand: "Samsung", price: 800 },
  { category: "Electronics", brand: "Sony", price: 950 },
  { category: "Apparel", brand: "Nike", price: 150 },
  { category: "Apparel", brand: "Adidas", price: 120 },
  { category: "Books", brand: "Penguin", price: 25 },
  { category: "Books", brand: "Penguin", price: 35 }
]);

Maintenant que vous avez des données, vous pouvez effectuer une agrégation. La commande suivante regroupe les documents par le champ category et calcule le prix total pour chaque catégorie en utilisant l'accumulateur $sum.

db.products.aggregate([
  {
    $group: {
      _id: "$category",
      totalPrice: { $sum: "$price" }
    }
  }
]);

Exemple de sortie :

[
  { "_id": "Books", "totalPrice": 60 },
  { "_id": "Apparel", "totalPrice": 270 },
  { "_id": "Electronics", "totalPrice": 2950 }
]

Décomposons l'étape d'agrégation :

  • db.products.aggregate([...]) : C'est la méthode utilisée pour effectuer une agrégation. Elle prend un tableau d'étapes, formant un pipeline.
  • $group : C'est l'opérateur d'étape qui regroupe les documents d'entrée.
  • _id: "$category" : Cette expression spécifie la clé de regroupement. Ici, nous regroupons par la valeur du champ category. Le préfixe $ indique un chemin de champ.
  • totalPrice: { $sum: "$price" } : C'est un accumulateur. Il définit un nouveau champ dans le document de sortie appelé totalPrice. L'opérateur $sum calcule la somme du champ price pour tous les documents du groupe.

Utiliser plusieurs accumulateurs

L'étape $group peut calculer plusieurs agrégations simultanément. Vous pouvez calculer des moyennes, trouver des valeurs minimales ou maximales, et compter des éléments dans chaque groupe. Cette étape montre comment utiliser plusieurs accumulateurs dans une seule étape $group.

Vous devriez toujours être dans le shell mongosh, en utilisant la base de données salesdb.

Écrivons une agrégation plus complexe qui calcule le prix total, le prix moyen et le nombre de produits pour chaque catégorie.

db.products.aggregate([
  {
    $group: {
      _id: "$category",
      totalPrice: { $sum: "$price" },
      averagePrice: { $avg: "$price" },
      productCount: { $sum: 1 }
    }
  }
]);

Exemple de sortie :

[
  {
    "_id": "Books",
    "totalPrice": 60,
    "averagePrice": 30,
    "productCount": 2
  },
  {
    "_id": "Apparel",
    "totalPrice": 270,
    "averagePrice": 135,
    "productCount": 2
  },
  {
    "_id": "Electronics",
    "totalPrice": 2950,
    "averagePrice": 983.3333333333334,
    "productCount": 3
  }
]

Voici les nouveaux accumulateurs que nous avons utilisés :

  • averagePrice: { $avg: "$price" } : L'opérateur $avg calcule la moyenne du champ price pour tous les documents du groupe.
  • productCount: { $sum: 1 } : C'est une façon courante de compter les documents dans un groupe. Pour chaque document, il ajoute 1 à la somme, ce qui compte effectivement les documents.

Filtrer les données groupées

Après avoir groupé les données, vous devez souvent filtrer les groupes en fonction des valeurs calculées. Par exemple, vous pourriez vouloir afficher uniquement les catégories dont les ventes totales dépassent un certain montant. L'étape $match est utilisée à cette fin. Elle peut être placée après une étape $group pour filtrer les documents groupés.

Trouvons les catégories dont le prix total des produits est supérieur à 500.

db.products.aggregate([
  {
    $group: {
      _id: "$category",
      totalPrice: { $sum: "$price" }
    }
  },
  {
    $match: {
      totalPrice: { $gt: 500 }
    }
  }
]);

Exemple de sortie :

[{ "_id": "Electronics", "totalPrice": 2950 }]

Dans ce pipeline :

  1. L'étape $group calcule d'abord le totalPrice pour chaque catégorie.
  2. Les documents de sortie de l'étape $group sont ensuite transmis à l'étape $match.
  3. L'étape $match filtre ces documents, ne conservant que ceux pour lesquels le champ totalPrice est supérieur ($gt) à 500.

Cela démontre la puissance du pipeline d'agrégation, où la sortie d'une étape devient l'entrée de la suivante.

Trier les données groupées

Une fois que vous avez vos données groupées et filtrées, l'étape finale consiste souvent à les trier. L'étape $sort vous permet d'ordonner les documents en fonction d'un ou plusieurs champs, soit par ordre croissant, soit par ordre décroissant.

Regroupons les produits par catégorie, calculons le prix total, puis trions les résultats par totalPrice en ordre décroissant (du plus élevé au plus bas).

db.products.aggregate([
  {
    $group: {
      _id: "$category",
      totalPrice: { $sum: "$price" }
    }
  },
  {
    $sort: {
      totalPrice: -1
    }
  }
]);

Exemple de sortie :

[
  { "_id": "Electronics", "totalPrice": 2950 },
  { "_id": "Apparel", "totalPrice": 270 },
  { "_id": "Books", "totalPrice": 60 }
]

L'étape $sort prend un document qui spécifie les champs par lesquels trier et l'ordre de tri :

  • totalPrice: -1 : Ceci trie les documents par le champ totalPrice. La valeur -1 spécifie un ordre décroissant. Pour trier par ordre croissant, vous utiliseriez 1.

Vous pouvez également trier par plusieurs champs. Par exemple, $sort: { category: 1, totalPrice: -1 } trierait d'abord par le nom de la catégorie par ordre alphabétique, puis par le prix total décroissant pour les catégories portant le même nom.

Remodeler la sortie avec $project

Parfois, le format de sortie de l'étape $group n'est pas exactement ce dont vous avez besoin. Par exemple, la clé de groupe est nommée _id par défaut. L'étape $project vous permet de remodeler les documents de sortie en ajoutant, supprimant ou renommant des champs.

Construisons un pipeline qui regroupe par catégorie, trie par prix total, puis remodèle la sortie pour avoir un nom de champ plus descriptif pour la catégorie.

db.products.aggregate([
  {
    $group: {
      _id: "$category",
      totalPrice: { $sum: "$price" }
    }
  },
  {
    $sort: {
      totalPrice: -1
    }
  },
  {
    $project: {
      _id: 0,
      category: "$_id",
      total: "$totalPrice"
    }
  }
]);

Exemple de sortie :

[
  { "category": "Electronics", "total": 2950 },
  { "category": "Apparel", "total": 270 },
  { "category": "Books", "total": 60 }
]

L'étape $project fonctionne comme suit :

  • _id: 0 : Ceci exclut le champ _id de la sortie. Par défaut, _id est toujours inclus sauf s'il est explicitement exclu.
  • category: "$_id" : Ceci crée un nouveau champ nommé category et lui assigne la valeur du champ _id existant.
  • total: "$totalPrice" : Ceci crée un nouveau champ nommé total et lui assigne la valeur du champ totalPrice.

L'utilisation de $project est un moyen puissant de formater la sortie finale de votre pipeline d'agrégation pour les applications ou les rapports.

Résumé

Dans ce laboratoire, vous avez appris à utiliser le pipeline d'agrégation MongoDB pour regrouper et analyser des données. Vous avez commencé par regrouper des documents avec l'opérateur $group et à calculer des sommes. Vous avez ensuite étendu cela en utilisant plusieurs accumulateurs comme $avg et $sum: 1 pour effectuer des calculs plus complexes. Vous avez également appris à chaîner des étapes d'agrégation, en utilisant $match pour filtrer vos résultats groupés, $sort pour les ordonner, et $project pour remodeler la sortie finale dans un format propre et lisible. Ce sont des compétences fondamentales pour tout développeur ou analyste de données travaillant avec MongoDB.