🛢️Parcours Fioul GroupéGuide pas à pas — MongoDB
Accueil › Parcours 1 · MongoDB
🍃 Parcours 1 — Modélisation NoSQL

Modéliser une base MongoDB, pas à pas

Un guide progressif pour construire un modèle de données propre. À chaque étape : un exemple complet sur une médiathèque, puis à toi de l'adapter au projet Fioul Groupé. On part de l'analyse du domaine et on va jusqu'aux agrégations et aux index.

1
J'observe l'exempleUne médiathèque : livres, auteurs, avis. Code complet et commenté.
2
J'adapte au fioulJe transpose la même idée aux campagnes, commandes et fournisseurs.
La clé du parcours — l'exemple « médiathèque » et le projet « fioul » ont la même forme. Garde cette correspondance sous les yeux :
Médiathèque (exemple)Rôle structurelFioul Groupé (à toi)
Livredocument racineCampagne
Avissous-documents embarquésCommande
Auteurentité référencéeFournisseur
note moyennevaleur calculée (agrégation)volume total → palier de prix
1 Étape 1

Analyser le domaine avant de coder

Avant toute requête, on identifie les entités, leurs attributs et surtout leurs relations (un-à-plusieurs, plusieurs-à-plusieurs). C'est cette analyse qui décidera, à l'étape 3, de ce qu'on embarque et de ce qu'on référence.

Exemple Médiathèque

Trois notions ressortent de l'énoncé « une médiathèque gère des livres, écrits par des auteurs, que les lecteurs notent » :

  • Auteur — nom, prénom, nationalité.
  • Livre — titre, ISBN, année ; écrit par un auteur.
  • Avis — pseudo, note /5, commentaire ; rattaché à un livre.

Relations

  • Un auteur écrit plusieurs livres (1‑N).
  • Un livre reçoit plusieurs avis (1‑N), qui n'existent pas sans lui.
À toi — Fioul Le domaine du projet

Reprends la démarche sur l'énoncé du fioul groupé et liste les entités, attributs et relations.

  • Identifie les entités : Campagne, Commande, Fournisseur, Utilisateur.
  • Pour chacune, écris ses attributs (ex. Campagne : zone, dateLimite, statut…).
  • Note les relations : une campagne a plusieurs commandes ; un fournisseur dessert plusieurs campagnes.
  • Repère celles qui n'existent pas sans leur parent (une commande sans campagne ?).
Indice — une commande ressemble beaucoup à un avis : elle n'a de sens qu'à l'intérieur d'une campagne.
2 Étape 2

Écrire et insérer le premier document

On traduit une entité en document JSON/BSON et on l'insère avec insertOne. Objectif : manipuler la structure de base d'un document et voir l'_id généré.

Exemple Un livre
// base "mediatheque", collection "livres"
use mediatheque

db.livres.insertOne({
  titre: "Le Comte de Monte-Cristo",
  isbn: "978-2070409709",
  anneePublication: 1844,
  genres: ["aventure", "roman"]
})

MongoDB ajoute automatiquement un _id (un ObjectId) : c'est la clé du document.

À toi — Fioul Une campagne
  • Crée la base fioul et la collection campagnes.
  • Insère une campagne pour Ladignac-le-Long avec zone, statut: "OUVERTE", dateLimite.
  • Utilise le type date : dateLimite: ISODate("2026-11-30").
  • Vérifie l'insertion avec db.campagnes.find().
Attention — une date écrite entre guillemets est une chaîne, pas une date. Utilise ISODate(...) pour pouvoir comparer et trier ensuite.
3 Étape 3

Embarquer ou référencer  ? La décision centrale

En NoSQL, on ne « normalise » pas par réflexe. La règle : on embarque ce qu'on lit toujours ensemble et qui appartient au parent ; on référence ce qui est partagé ou volumineux. C'est le choix qui structure toute la suite.

Exemple Avis embarqués, auteur référencé

On lit toujours un livre avec ses avis → on les embarque. Un auteur est partagé par plusieurs livres → on le référence par son _id.

db.auteurs.insertOne({ _id: "dumas",
  nom: "Dumas", prenom: "Alexandre" })

db.livres.updateOne(
  { isbn: "978-2070409709" },
  { $set: {
    auteurId: "dumas",          // référence
    avis: [                    // embarqué
      { pseudo: "Léa", note: 5,
        commentaire: "Un classique !" }
    ]
  }}
)
À toi — Fioul Commandes & fournisseur
  • Embarque les commandes dans la campagne (on affiche toujours une campagne avec ses inscriptions).
  • Référence le fournisseur par un fournisseurId (il sert plusieurs campagnes).
  • Crée un document fournisseurs avec ses paliers (volumeMin → prixLitre).
  • Justifie chaque choix en une phrase dans ton README.
À débattre en classe — et si une campagne pouvait dépasser des milliers de commandes ? À partir de quel volume l'embarquement devient-il un problème ? (limite des 16 Mo par document).
4 Étape 4

Modifier un tableau embarqué

Ajouter un sous-document à un tableau sans réécrire tout le document : c'est le rôle des opérateurs de tableaux ($push, $pull, $elemMatch).

Exemple Ajouter un avis
db.livres.updateOne(
  { isbn: "978-2070409709" },
  { $push: { avis: {
      pseudo: "Karim", note: 4,
      commentaire: "Long mais prenant",
      date: new Date()
  }}}
)

$push ajoute un élément au tableau avis. Pour retirer un avis : $pull.

À toi — Fioul Rejoindre une campagne
  • Avec $push, ajoute une commande (litres, commune, adresse) au tableau commandes d'une campagne.
  • Ajoute-en 3 ou 4 pour préparer l'agrégation de l'étape 6.
  • Teste $pull pour désinscrire un participant.
Anticipe l'API — ce $push deviendra bientôt l'endpoint POST /campagnes/{id}/commandes côté Spring.
5 Étape 5

Interroger : filtres & projection

Retrouver les bons documents (find + opérateurs), et ne renvoyer que les champs utiles (projection). C'est la base des futurs endpoints de lecture.

Exemple Filtrer des livres
// livres parus après 1900, triés récents d'abord
db.livres.find(
  { anneePublication: { $gt: 1900 } },
  { titre: 1, anneePublication: 1, _id: 0 } // projection
).sort({ anneePublication: -1 })
À toi — Fioul Campagnes ouvertes
  • Liste les campagnes statut: "OUVERTE" d'une zone donnée.
  • Ne renvoie que zone, dateLimite, fournisseurId (projection).
  • Trie par dateLimite croissante (les plus urgentes d'abord).
  • Ajoute un filtre : seulement celles dont la dateLimite n'est pas dépassée ($gte: new Date()).
6 Étape 6

Agréger : le cœur du projet

Le pipeline d'agrégation transforme les données : on déplie un tableau ($unwind), on regroupe ($group) et on calcule ($sum, $avg). C'est ainsi qu'on obtiendra le volume total d'une campagne et son palier de prix.

Exemple Note moyenne par livre
db.livres.aggregate([
  { $unwind: "$avis" },              // une ligne par avis
  { $group: {
      _id: "$titre",
      noteMoyenne: { $avg: "$avis.note" },
      nbAvis:      { $sum: 1 }
  }},
  { $sort: { noteMoyenne: -1 } }
])

Résultat : chaque livre avec sa note moyenne et son nombre d'avis.

À toi — Fioul Volume total & palier
  • Calcule le volume total par campagne : $unwind: "$commandes" puis $sum: "$commandes.litres".
  • Compte le nombre de participants ($sum: 1).
  • Déduis le palier de prix atteint : compare le volume aux paliers du fournisseur ($lookup pour joindre le fournisseur, puis logique conditionnelle).
Défi bonus — avec $bucket, range les campagnes par tranche de volume (0‑3000, 3000‑8000, 8000+ L).
7 Étape 7

Fiabiliser : validation, index & géo

Un modèle prêt pour la production : on valide la forme des documents ($jsonSchema), on indexe les champs interrogés, et on prépare la recherche géospatiale par zone.

Exemple Schéma & index
// imposer titre + isbn, note entre 0 et 5
db.createCollection("livres", { validator: {
  $jsonSchema: {
    required: ["titre", "isbn"],
    properties: {
      isbn: { bsonType: "string" }
    }
}}})

db.livres.createIndex({ isbn: 1 }, { unique: true })
À toi — Fioul Robustesse du modèle
  • Écris un $jsonSchema pour campagnes : zone et statut requis, statut dans une liste (enum).
  • Indexe statut + zone (index composé) pour la recherche de l'étape 5.
  • Ajoute un champ localisation de type Point et un index 2dsphere.
  • Écris une requête $near : les campagnes à moins de 20 km d'un point.
Bilan du parcours — tu as un modèle validé, indexé, avec les agrégations qui alimenteront l'API. Prochain arrêt : exposer tout ça en REST avec Spring Boot.
+ Pour aller plus loin

Tutoriels & ressources MongoDB

Des ressources gratuites pour réviser autrement ou approfondir. Commence par W3Schools pour tester vite une requête, et MongoDB University pour un parcours de fond avec labs interactifs.

Conseil d'usage — ces ressources complètent le parcours mais ne remplacent pas l'adaptation au projet fioul : quel que soit le tutoriel suivi, l'objectif reste de transposer les notions aux campagnes, commandes et fournisseurs.
← Retour au portail