Ce chapitre présente une explication détaillée de l'analyse statistique de MongoDB, principalement réalisée à travers le Pipeline d'agrégation. Cela est similaire à l'instruction "group by" en SQL. Dans le shell MongoDB, l'analyse statistique est mise en œuvre en utilisant la fonction db.collection.aggregate().

Tutoriel préalable

Pipeline d'agrégation MongoDB

Étapes générales

  • Utiliser $match pour filtrer les données cibles
  • Utiliser $group pour regrouper et calculer les données
  • Utiliser $sort pour trier les résultats (optionnel)

Données de test

Les données dans la collection orders sont les suivantes :

{ _id: 1, cust_id: "abc1", ord_date: ISODate("2012-11-02T17:04:11.102Z"), status: "A", amount: 50 }
{ _id: 2, cust_id: "xyz1", ord_date: ISODate("2013-10-01T17:04:11.102Z"), status: "A", amount: 100 }
{ _id: 3, cust_id: "xyz1", ord_date: ISODate("2013-10-12T17:04:11.102Z"), status: "D", amount: 25 }
{ _id: 4, cust_id: "xyz1", ord_date: ISODate("2013-10-11T17:04:11.102Z"), status: "D", amount: 125 }
{ _id: 5, cust_id: "abc1", ord_date: ISODate("2013-11-12T17:04:11.102Z"), status: "A", amount: 25 }

Fonction d'agrégation

db.collection.aggregate(pipeline) Explication :

  • Le pipeline prend un paramètre de tableau, où chaque élément représente une étape de traitement.

Exemple

db.orders.aggregate([
                     { $match: { status: "A" } },  // Première étape
                     { $group: { _id: "$cust_id", total: { $sum: "$amount" } } },   // Deuxième étape
                     { $sort: { total: -1 } }  // Troisième étape
                   ])

Equivalent SQL :

select sum(amount) as total from orders 
        where status="A" 
        group by cust_id 
        order by total desc

Étape $match

Format :

{ $match: { <query> } }

Explication :

  • <query> Conditions de requête MongoDB

Utilisé pour définir les conditions de requête. Si $match est ignoré, cela implique la requête de toutes les données.

Astuce : Si vous n'êtes pas familier avec la syntaxe de requête MongoDB, veuillez vous référer aux chapitres précédents.

Étape $group

Similaire à la clause group by en SQL, elle est utilisée pour regrouper les données, puis effectuer une série de calculs statistiques sur les données groupées.

Utilisation de base de l'étape $group

Syntaxe :

{
  $group:
    {
      _id: <expression>, // Condition de regroupement, par exemple : regrouper par quel champ
      <field1>: { <accumulateur1> : <expression1> },  // Opération d'agrégation, vous pouvez ajouter N opérations d'agrégation
      ...
    }
 }

Explication :

  • - Nom de l'indicateur statistique personnalisé, peut être N au total
  • - Fonction d'agrégation, similaire aux fonctions d'agrégation SQL telles que sum, avg et autres fonctions d'agrégation, la différence est que les fonctions d'agrégation de MongoDB sont nommées avec $ comme préfixe, par exemple : $sum, $avg
  • - Paramètre de la fonction d'agrégation, généralement la valeur du champ à compter, en faisant référence aux champs du document en utilisant le format "$nom du champ"

Exemple :

db.orders.aggregate([
                     {
					 	$group: { 
							_id: "$cust_id",
							total: { $sum: "$amount" }, // Ajouter le premier indicateur calculé total, en utilisant l'opérateur de sommation $sum
							amount_avg: {$avg: "$amount"}  // Ajouter le deuxième indicateur calculé avg, en utilisant l'opérateur de calcul de moyenne $avg
						} 
					}
               ])

Résultat :

{ "_id" : "abc1", "total" : 75, "amount_avg" : 37.5 }
{ "_id" : "xyz1", "total" : 250, "amount_avg" : 83.33333333333333 }

Equivalent SQL :

select 
	sum(amount) as  total,
	avg(amount) as amount_avg
from orders 
group by cust_id

Fonctions d'agrégation $group

Les fonctions d'agrégation couramment utilisées pour $group sont les suivantes:

Opérateur Description Exemple
$avg Calculer la moyenne {$avg: "$amount"}
$sum Somme {$sum: "$amount"}
$max Valeur maximale {$max: "$amount"}
$min Valeur minimale {$min: "$amount"}
$first Retourne les données après regroupement, le contenu du premier document {$first: "$amount"}
$last Retourne les données après regroupement, le contenu du dernier document {$last: "$amount"}
$push Retourne les données après regroupement { $push: { ord_date: "$ord_date", amount: "$amount" }}
$addToSet Retourne les données après regroupement, différent de $push car il supprime les doublons { $addToSet: "$amount" }

Exemple de $push

db.orders.aggregate(
   [
     {
       $group:
         {
           _id: "$cust_id",
           all: { $push: { ord_date: "$ord_date", amount: "$amount" } } // Valeurs des champs ord_date et amount
         }
     }
   ]
)

Résultat

{ "_id" : "abc1", "all" : [ { "ord_date" : "2021-04-18 00:00:00", "amount" : 50 }, { "ord_date" : "2021-04-21 00:00:00", "amount" : 25 } ] }
{ "_id" : "xyz1", "all" : [ { "ord_date" : "2021-04-18 00:00:00", "amount" : 100 }, { "ord_date" : "2021-04-20 00:00:00", "amount" : 25 }, { "ord_date" : "2021-04-21 00:00:00", "amount" : 125 } ] }

Exemple de $addToSet

db.orders.aggregate(
   [
     {
       $group:
         {
           _id: "$cust_id",
           all_amount: { $addToSet: "$amount" } // Retourne toutes les valeurs de montant distinctes
         }
     }
   ]
)

Résultat

{ "_id" : "abc1", "all_amount" : [ 25, 50 ] }
{ "_id" : "xyz1", "all_amount" : [ 100, 25, 125 ] }

$sort:

L'étape $sort est généralement placée à la fin pour trier les données agrégées.

Format:

{ $sort: { <champ1>: <ordre de tri>, <champ2>: <ordre de tri> ... } }

Explication:

  • , - Les noms des champs à trier, prend en charge plusieurs champs.
  • - La direction du tri, -1 pour descendante, 1 pour ascendante.

Exemple:

db.orders.aggregate([
                     { $match: { status: "A" } },
                     { $group: { _id: "$cust_id", total: { $sum: "$amount" } } },
                     { $sort: { total: -1 } }
                   ])

Pagination d'Agrégats

Nous pouvons mettre en œuvre la pagination en utilisant les opérateurs $limit et $skip.

Exemple:

db.orders.aggregate([
                     { $match: { status: "A" } },
                     { $group: { _id: "$cust_id", total: { $sum: "$amount" } } },
                     { $sort: { total: -1 } },
                     { $limit: 5 }, // Limite le nombre d'enregistrements retournés, similaire à la taille de la page en pagination.
                     { $skip: 1 } // Passe un certain nombre d'enregistrements, similaire au décalage en SQL.
                   ])