Après avoir compris les fondamentaux de MongoDB et installé ton instance Docker, il est temps de mettre les mains dans le moteur. Les opérations CRUD — Create, Read, Update, Delete — sont le cœur de toute interaction avec une base de données. En MongoDB, elles s’exécutent via mongosh avec une syntaxe JavaScript fluide et intuitive.
Ce chapitre couvre l’intégralité des opérations CRUD, les filtres avancés avec opérateurs, les projections pour contrôler les données retournées, et les types BSON qui font la richesse de MongoDB.
🎯 Objectifs de la leçon
- Maîtriser
insertOne,insertMany,find,updateOne,updateMany,deleteOne,deleteMany - Utiliser les opérateurs de comparaison et logiques pour des requêtes précises
- Contrôler les résultats avec les projections, le tri et la pagination
- Comprendre les types BSON et savoir quand les utiliser
Create : insérer des documents
MongoDB propose deux méthodes d’insertion. insertOne pour un seul document, insertMany pour plusieurs d’un coup. La méthode crée automatiquement la collection si elle n’existe pas encore — pas besoin de CREATE TABLE.
Voici comment insérer un document unique. MongoDB génère automatiquement un _id de type ObjectId si tu n’en fournis pas :
db.servers.insertOne({
hostname: "web-01",
ip: "10.0.1.10",
role: "webserver",
cpu_cores: 4,
ram_gb: 16,
status: "running",
tags: ["production", "europe-west"],
metrics: { cpu_usage: 45.2, ram_usage: 72.1 }
})
// { acknowledged: true, insertedId: ObjectId('65a1b2c3...') }
Pour insérer plusieurs documents en une seule opération, utilise insertMany avec un tableau. C’est nettement plus performant que des insertOne en boucle — une seule requête réseau au lieu de N :
db.servers.insertMany([
{ hostname: "web-02", ip: "10.0.1.11", role: "webserver",
status: "running", tags: ["production"] },
{ hostname: "db-01", ip: "10.0.2.10", role: "database",
cpu_cores: 8, ram_gb: 64, status: "running",
tags: ["production"], services: ["postgresql"] },
{ hostname: "staging-01", ip: "10.0.3.10", role: "all-in-one",
status: "stopped", tags: ["staging"] }
])
Remarque : db-01 a des champs services et ram_gb que staging-01 n’a pas. MongoDB accepte sans broncher — c’est la flexibilité du schéma document.
⚠️ Attention : Si tu fournis un
_idmanuellement et qu’il existe déjà, MongoDB renvoie une erreurE11000 duplicate key error. En production, préfère laisser MongoDB générer les ObjectId automatiquement sauf besoin spécifique (clé naturelle comme un code pays).
Read : requêtes et filtres
C’est la partie la plus riche de MongoDB. Les méthodes find et findOne acceptent un filtre (premier argument) et une projection optionnelle (second argument) pour contrôler quels champs retourner.
Filtres simples et opérateurs de comparaison
Un filtre est un objet JSON qui décrit les critères de sélection. Sans filtre, find() retourne tous les documents. Avec un filtre, seuls les documents correspondants sont retournés :
// Un seul critère
db.servers.find({ status: "running" })
// Plusieurs critères (AND implicite)
db.servers.find({ role: "webserver", status: "running" })
// Opérateurs de comparaison
db.servers.find({ cpu_cores: { $gt: 4 } }) // supérieur à 4
db.servers.find({ ram_gb: { $gte: 16, $lte: 64 } }) // entre 16 et 64
db.servers.find({ role: { $in: ["webserver", "database"] } }) // dans la liste
Les opérateurs essentiels : $eq (égal), $ne (différent), $gt/$gte (supérieur), $lt/$lte (inférieur), $in/$nin (dans/pas dans une liste), $exists (champ présent ou absent).
Opérateurs logiques et requêtes imbriquées
Pour des conditions plus complexes, MongoDB propose $and, $or et $not. Le $and est implicite quand tu mets plusieurs critères dans le même objet, mais tu en as besoin explicitement quand tu combines avec $or :
// OR : serveurs web OU database
db.servers.find({
$or: [{ role: "webserver" }, { role: "database" }]
})
// Combiné : (web OU db) ET status running
db.servers.find({
$and: [
{ $or: [{ role: "webserver" }, { role: "database" }] },
{ status: "running" }
]
})
// Dot notation pour les sous-documents
db.servers.find({ "metrics.cpu_usage": { $gt: 50 } })
💡 Tip DevOps : La dot notation (
"metrics.cpu_usage") est l’une des fonctionnalités les plus puissantes de MongoDB. Elle permet de requêter n’importe quel niveau d’imbrication sans jointure. En monitoring, c’est indispensable pour filtrer sur des métriques imbriquées.
Projections : contrôler les champs retournés
Par défaut, MongoDB renvoie le document complet. Les projections permettent de sélectionner uniquement les champs utiles — essentiel pour les performances quand tes documents sont volumineux :
// Inclure seulement hostname et status (+ _id par défaut)
db.servers.find({ status: "running" }, { hostname: 1, status: 1 })
// Exclure _id et metrics
db.servers.find({}, { _id: 0, hostname: 1, ip: 1, role: 1 })
Règle importante : tu ne peux pas mélanger inclusion (1) et exclusion (0) dans la même projection. La seule exception est _id: 0 qui peut accompagner des inclusions.
Tri, pagination et comptage
Pour exploiter les résultats, MongoDB propose le chaînage de méthodes — sort, limit, skip et countDocuments :
// Top 3 serveurs par RAM décroissante
db.servers.find({}, { _id: 0, hostname: 1, ram_gb: 1 })
.sort({ ram_gb: -1 }).limit(3)
// Pagination : page 2, 10 résultats par page
db.servers.find().skip(10).limit(10)
// Compter les serveurs en production
db.servers.countDocuments({ tags: "production" })
🧠 À retenir :
sort()s’exécute toujours avantlimit(), quel que soit l’ordre d’écriture dans la chaîne. MongoDB optimise automatiquement. Pour la pagination en production, préfère un curseur basé sur_idplutôt queskip()qui devient lent sur de gros volumes.
Update : modifier des documents
MongoDB sépare la mise à jour unitaire (updateOne) de la mise à jour en masse (updateMany). Les deux prennent un filtre et un objet de modification utilisant des opérateurs spéciaux.
L’opérateur $set modifie ou ajoute un champ. $inc incrémente une valeur numérique. $push ajoute un élément à un tableau. $pull en retire un. $unset supprime un champ :
// Mettre à jour les métriques d'un serveur
db.servers.updateOne(
{ hostname: "web-01" },
{ $set: { "metrics.cpu_usage": 52.1 }, $inc: { ram_gb: 16 } }
)
// Ajouter un tag à tous les serveurs de production
db.servers.updateMany(
{ tags: "production" },
{ $addToSet: { tags: "monitored" } } // addToSet évite les doublons
)
// Upsert : créer si inexistant, mettre à jour sinon
db.servers.updateOne(
{ hostname: "cache-01" },
{ $set: { role: "cache", status: "running", ip: "10.0.5.10" } },
{ upsert: true }
)
🔥 Cas réel en entreprise : Dans un système de monitoring, un agent collecte les métriques toutes les 30 secondes et fait un
updateOneavec$setsur les métriques courantes. L’upsert: truepermet de gérer automatiquement les nouveaux serveurs qui apparaissent — pas besoin de les pré-enregistrer. C’est le pattern le plus courant en infra as code.
Delete : supprimer des documents
La suppression suit la même logique que les autres opérations : deleteOne pour un document, deleteMany pour plusieurs. Le filtre détermine ce qui est supprimé :
// Supprimer un serveur spécifique (toujours par _id si possible)
db.servers.deleteOne({ hostname: "staging-01" })
// Supprimer tous les serveurs arrêtés
db.servers.deleteMany({ status: "stopped" })
// Vider une collection (tous les documents, garde la collection)
db.servers.deleteMany({})
// Supprimer la collection elle-même
db.servers.drop()
⚠️ Attention :
deleteMany({})sans filtre supprime tous les documents de la collection. C’est irréversible. En production, protège-toi avec des backups réguliers (mongodump) et des rôles utilisateurs restreints qui n’ont pas le droitdelete. Un junior avec accès admin sur la prod, c’est une bombe à retardement.
Les types BSON essentiels
MongoDB stocke les données en BSON (Binary JSON), un format qui étend JSON avec des types supplémentaires. Les plus importants à connaître :
ObjectId : identifiant unique de 12 octets, auto-généré pour _id. Contient un timestamp — tu peux extraire la date de création avec oid.getTimestamp().
Date : utilise new Date() ou ISODate("2026-03-20T10:00:00Z"). Ne stocke jamais une date en string — tu perds le tri et les comparaisons.
Decimal128 : NumberDecimal("19.99") pour les valeurs financières. Les Double classiques ont des erreurs d’arrondi (19.99 peut devenir 19.990000000000002).
Array : les tableaux sont des citoyens de première classe. Tu peux filtrer sur leur contenu ({ tags: "production" } matche si “production” est dans le tableau) et les manipuler avec $push, $pull, $addToSet.
🔥 Cas réel en entreprise : Une fintech stockait les montants de transactions en
Double. Au bout de 6 mois, les rapprochements comptables ne tombaient plus juste — des centimes d’écart qui s’accumulaient. Migration versDecimal128et problème résolu. Règle d’or : si c’est de l’argent, c’estNumberDecimal.
Résumé
Les opérations CRUD de MongoDB sont expressives et puissantes. L’insertion est flexible (pas de schéma à déclarer), les requêtes combinent filtres, opérateurs et projections de manière intuitive, les mises à jour sont chirurgicales grâce aux opérateurs $set, $inc, $push, et la suppression reste simple mais dangereuse sans garde-fous.
🧠 À retenir : Utilise
insertManyplutôt que des boucles d’insertOne. Maîtrise la dot notation pour les sous-documents. Préfère$addToSetà$pushpour éviter les doublons. Et en production, ne donne jamais les droitsdeleteà tout le monde — undeleteMany({})mal placé et c’est la catastrophe.
➡️ La suite : Chapitre 3 — Agrégation et index MongoDB
Contenu réservé aux abonnés
Ce chapitre fait partie de la formation complète. Abonne-toi pour débloquer tous les contenus.
Débloquer pour 29 CHF/moisLe chapitre 1 de chaque formation est gratuit.
Série pas encore débloquée
Termine la série prérequise d'abord pour accéder à ce contenu.
Aller à la série prérequiseSur cette page
Articles liés
MongoDB : les bases du NoSQL
Comprends la différence NoSQL vs SQL, les concepts fondamentaux de MongoDB (documents, collections, bases), et installe MongoDB avec Docker.
Agrégation et indexation
Maîtrise l'aggregation pipeline MongoDB ($match, $group, $sort, $lookup) et optimise tes requêtes avec les index (simple, composé, texte).
MongoDB en production : réplication et sharding
Schema validation, relations embedded vs references, intégration Python avec pymongo, MongoDB Atlas et stratégies de backup/restauration.