| Médiathèque (exemple) | Rôle structurel | Fioul Groupé (à toi) |
|---|---|---|
| Livre | document racine | Campagne |
| Avis | sous-documents embarqués | Commande |
| Auteur | entité référencée | Fournisseur |
| note moyenne | valeur calculée (agrégation) | volume total → palier de prix |
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.
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.
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 ?).
É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é.
// 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.
- Crée la base
fioulet la collectioncampagnes. - 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().
ISODate(...) pour pouvoir comparer et trier ensuite.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.
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 !" }
]
}}
)
- Embarque les
commandesdans la campagne (on affiche toujours une campagne avec ses inscriptions). - Référence le
fournisseurpar unfournisseurId(il sert plusieurs campagnes). - Crée un document
fournisseursavec sespaliers(volumeMin → prixLitre). - Justifie chaque choix en une phrase dans ton README.
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).
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.
- Avec
$push, ajoute une commande (litres,commune,adresse) au tableaucommandesd'une campagne. - Ajoute-en 3 ou 4 pour préparer l'agrégation de l'étape 6.
- Teste
$pullpour désinscrire un participant.
$push deviendra bientôt l'endpoint POST /campagnes/{id}/commandes côté Spring.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.
// 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 })
- Liste les campagnes
statut: "OUVERTE"d'unezonedonnée. - Ne renvoie que
zone,dateLimite,fournisseurId(projection). - Trie par
dateLimitecroissante (les plus urgentes d'abord). - Ajoute un filtre : seulement celles dont la
dateLimiten'est pas dépassée ($gte: new Date()).
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.
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.
- 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
paliersdu fournisseur ($lookuppour joindre le fournisseur, puis logique conditionnelle).
$bucket, range les campagnes par tranche de volume (0‑3000, 3000‑8000, 8000+ L).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.
// 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 })
- Écris un
$jsonSchemapourcampagnes:zoneetstatutrequis,statutdans une liste (enum). - Indexe
statut+zone(index composé) pour la recherche de l'étape 5. - Ajoute un champ
localisationde typePointet un index2dsphere. - Écris une requête
$near: les campagnes à moins de 20 km d'un point.
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.
campagnes, commandes et fournisseurs.