Maîtriser le framework d'agrégation de MongoDB

Le framework d'agrégation de MongoDB repose sur le concept de pipeline. Les documents entrent dans un pipeline composé de plusieurs étapes, où ils sont transformés, filtrés ou regroupés avant de produire un résultat final.

Préparation des données de test

Pour illustrer ces concepts, nous allons utiliser une collection nommée membres contenant des informations sur des utilisateurs, leurs âges, leur genre et leurs coordonnées géographiques.

db.membres.insertMany([
    {"nom": "Alice", "age": 22, "genre": "F", "actif": true, "localisation": [113, 23]},
    {"nom": "Bob", "age": 25, "genre": "M", "actif": true, "localisation": [108, 33]},
    {"nom": "Charlie", "age": 25, "genre": "M", "actif": true, "localisation": [114, 25]},
    {"nom": "David", "age": 30, "genre": "M", "actif": true, "localisation": [109, 23]},
    {"nom": "Eve", "age": 22, "genre": "F", "actif": true, "localisation": [110, 22]},
    {"nom": "Frank", "age": 28, "genre": "M", "actif": true, "localisation": [113, 25]},
    {"nom": "Grace", "age": 30, "genre": "F", "actif": true, "localisation": [110, 23]},
    {"nom": "Heidi", "age": 35, "genre": "F", "actif": true, "localisation": [111, 33]}
]);

Les étapes prnicipales du pipeline

Chaque étape commence par un opérateur spécifique qui définit l'action à réaliser sur les documents entrants.

  • $project : Sélectionne, renomme ou crée de nouveaux champs.
  • $match : Filtre les documents selon des critères précis (identique à find()).
  • $limit / $skip : Contrôle le nombre de documents retournés (pagination).
  • $sort : Trie les documents.
  • $group : Regroupe les documents pour effectuer des calculs statistiques.
  • $unwind : Décompose un tableau contenu dans un document en plusieurs documents.
  • $geoNear : Sélectionne des documents à proximité d'un point géographique.

Filtrage et Projection

L'exemple suivant montre comment filtrer les utilisateurs de 25 ans et ne renvoyer que leur nom.

db.membres.aggregate([
    { $match: { "age": 25 } },
    { $project: { "_id": 0, "nom": 1 } }
]);

Pagination et Tri

Pour trier par âge croissant et ignorer les deux premires résultats :

db.membres.aggregate([
    { $sort: { "age": 1 } },
    { $skip: 2 },
    { $limit: 3 }
]);

Recherche Géographique

Pour utiliser $geoNear, un index de type 2d ou 2dsphere est requis.

db.membres.createIndex({ "localisation": "2d" });

db.membres.aggregate([
    {
        $geoNear: {
            "near": [113, 24],
            "distanceField": "distance_calculée",
            "spherical": true
        }
    },
    { $limit: 1 }
]);

L'opérateur de regroupement ($group)

L'étape $group est essentielle pour les rapports et les statistiques. Elle utilise des accumulateurs pour traiter les données groupées.

db.membres.aggregate([
    {
        $group: {
            "_id": "$genre",
            "age_minimum": { $min: "$age" },
            "age_maximum": { $max: "$age" },
            "age_moyen": { $avg: "$age" },
            "nombre_total": { $sum: 1 }
        }
    }
]);

Accumulateurs courants :

  • $sum : Additionne les valeurs (ou compte les documents avec 1).
  • $avg : Calcule la moyenne.
  • $push : Insère des valeurs dans un tableau final.
  • $addToSet : Insère des valeurs uniques dans un tableau.
  • $first / $last : Récupère la première ou dernière valeur rencontrée.

Exemple avec $push pour lister les noms par genre :

db.membres.aggregate([
    { $group: { "_id": "$genre", "liste_noms": { $push: "$nom" } } }
]);

Opérateurs arithmétiques et de chaînes de caractères

Ces opérateurs s'utilisent généralement à l'intérieur d'un $project pour tranfsormer les données à la volée.

Calculs mathématiques

db.membres.aggregate([
    { 
        $project: { 
            "nom": 1, 
            "age_dans_cinq_ans": { $add: ["$age", 5] },
            "annee_naissance_approx": { $subtract: [2023, "$age"] }
        } 
    }
]);

Manipulation de chaînes

Fusionner des champs ou changer la casse :

db.membres.aggregate([
    { 
        $project: { 
            "identite": { $concat: ["$nom", " - ", "$genre"] },
            "nom_majuscule": { $toUpper: "$nom" }
        } 
    }
]);

Étiquettes: MongoDB NoSQL aggregation-framework database-queries

Publié le 21 juin à 19h36