đ MongoDB â NoSQL, RĂ©plication, SĂ©curitĂ© & Tuning
Guide opérationnel complet : Installation, CRUD, Indexation, Replica Sets & Intégration Django.
Concepts NoSQL
SQL (Relationnel) vs NoSQL (Non-relationnel).
NoSQL SQLMongoDB : Documents
Base de données de Documents (BSON/JSON).
Document BSONArchitecture
mongod, mongos, Replica Set, Sharding.
Installation Linux
apt (Ubuntu) & dnf (RHEL/Rocky), mongod.conf.
Installation (Docker)
docker run, docker-compose (avec UI Mongo Express).
Outils : mongosh & Compass
mongosh (CLI), Compass (UI Officielle).
DBs & Collections
use [db], db.createCollection(), show dbs.
Create (insert)
insertOne(), insertMany(), ObjectId().
Read (find)
find(), findOne(), .pretty(), {key: val}.
OpĂ©rateurs de RequĂȘte
$gt, $lt, $in, $or, $regex, $exists.
Update (Opérateurs)
updateOne, updateMany, $set, $unset, $inc.
Delete (delete)
deleteOne(), deleteMany(), drop().
Indexation : Concept
_id (défaut), COLLSCAN vs IXSCAN.
Indexation : Gestion
createIndex(), getIndexes(), explain().
Indexation : Types
Index Composé, Text (full-text), TTL, Sparse.
Compound TextRéplication (Replica Set)
Concept (HA), Primaire, Secondaire, Arbiter.
Replica Set HARéplication (Setup)
rs.initiate(), rs.add(), rs.status().
Aggregation Pipeline
$match, $group, $sort, $project.
Sécurité (Authentification)
security.authorization, createUser, auth().
Tuning (Performance)
explain(), mongotop, mongostat, WiredTiger.
Intégration Django (Djongo)
pip install djongo, settings.py (DATABASES).
Cheat-sheet mongosh
Commandes CRUD (find, insert, update).
SQL (ModĂšle Relationnel) (ex: PostgreSQL, MariaDB)
Analogie : Un tableur Excel (Lignes & Colonnes).
- Schéma : Rigide (
CREATE TABLE). Toutes les lignes doivent avoir les mĂȘmes colonnes. - Relations : DonnĂ©es normalisĂ©es. On utilise des
JOINpour lier (ex:usersJOINcommandes). - Cohérence : Stricte (Transactions ACID).
- Usage : Données structurées, finance, comptabilité.
NoSQL ("Not Only SQL") (ex: MongoDB, Redis)
Analogie : Un dossier de documents JSON.
- Schéma : Flexible (Dynamique). Chaque document peut avoir des champs différents.
- Relations : Données dénormalisées (imbriquées). On évite les
JOIN. L'objet "commande" peut contenir l'objet "utilisateur". - Scalabilité : Scalabilité horizontale (Sharding) facile.
- Usage : Big Data, données non structurées (logs), IoT, APIs rapides.
4 Types Principaux de NoSQL
| Type | Exemple | Usage |
|---|---|---|
| Document | MongoDB, CouchDB | Le plus courant. Stockage JSON (BSON). |
| ClĂ©-Valeur (K/V) | Redis, Memcached | Cache, Sessions (ExtrĂȘmement rapide). |
| Colonne Large | Cassandra, ScyllaDB | Big Data, IoT (écriture massive). |
| Graphe | Neo4j | Réseaux sociaux, détection de fraude (relations). |
La BDD NoSQL de type Document
MongoDB est la BDD NoSQL la plus populaire. Elle stocke les données non pas en lignes, mais en Documents.
Un Document est un objet BSON (Binary JSON). C'est du JSON binaire, qui supporte plus de types de données (ex: Date, ObjectId, Int64).
Exemple de Document (JSON)
{
"_id": ObjectId("67f51..."), // Clé primaire (gérée auto)
"titre": "Mon Article",
"contenu": "Texte de l'article...",
"status": "publie",
"tags": ["mongo", "nosql", "guide"], // Array (natif)
"auteur": { // Objet imbriqué (dénormalisation)
"nom": "Alice",
"email": "alice@mail.com"
},
"date_pub": ISODate("2025-11-01T10:00:00Z"),
"vues": 1500
}Les Processus MongoDB
mongod(Daemon) : C'est le **serveur de BDD** principal. Il gĂšre les donnĂ©es, les index, et exĂ©cute les requĂȘtes. (Unmysqldoupostgres).mongosh(Shell) : Le client CLI (moderne) pour se connecter Ămongod.mongos(Shard) : (AvancĂ©) Le **routeur** de requĂȘtes. UtilisĂ© *uniquement* dans un cluster "ShardĂ©" (voir onglet 2). Il route les requĂȘtes vers le bon Shard.
Réplication (Replica Set) - (Haute Disponibilité)
La **Haute Disponibilité (HA)** est gérée par un **Replica Set**. C'est un groupe de 3+ serveurs mongod qui se copient les uns les autres. (Voir 3.4).
(1 Primaire, 2 Secondaires) Primaire (Ăcritures) -> (Copie) -> Secondaire 1 (Lectures) | ^ +---- (Copie) --------------------+--> Secondaire 2 (Lectures)
Sharding (Scalabilité Horizontale)
La **Scalabilité Horizontale** (gestion de To de données) est gérée par le **Sharding**. Les données sont "partitionnées" (shardées) sur plusieurs Replica Sets.
(App) -> [mongos (Routeur)]
|
+-------+---------+
| |
⌠âŒ
[Replica Set A] [Replica Set B]
(Shard 1: A-M) (Shard 2: N-Z)
Ubuntu / Debian (DépÎt officiel MongoDB)
# (Ne PAS utiliser 'apt install mongodb' des dépÎts Ubuntu) # 1. Ajouter la clé GPG wget -qO - https://www.mongodb.org/static/pgp/server-7.0.asc | sudo gpg --dearmor -o /usr/share/keyrings/mongodb-server-7.0.gpg # 2. Ajouter le dépÎt (Ex: Ubuntu 22.04) echo "deb [ signed-by=/usr/share/keyrings/mongodb-server-7.0.gpg ] https://repo.mongodb.org/apt/ubuntu jammy/mongodb-org/7.0 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-7.0.list # 3. Installer sudo apt-get update sudo apt-get install -y mongodb-org
RHEL / Rocky / AlmaLinux (DépÎt officiel)
# 1. Créer le fichier .repo sudo vi /etc/yum.repos.d/mongodb-org-7.0.repo # Coller ceci dans le fichier : [mongodb-org-7.0] name=MongoDB Repository baseurl=https://repo.mongodb.org/yum/redhat/9/mongodb-org/7.0/x86_64/ gpgcheck=1 enabled=1 gpgkey=https://www.mongodb.org/static/pgp/server-7.0.asc # 2. Installer sudo dnf install -y mongodb-org
Post-Installation (systemd & Config)
# Activer au démarrage sudo systemctl enable --now mongod # Vérifier le statut sudo systemctl status mongod
Fichier de configuration : mongod.conf
Emplacement : /etc/mongod.conf (YAML)
storage: dbPath: /var/lib/mongo # (OĂč sont les donnĂ©es) net: port: 27017 bindIp: 127.0.0.1 # (DĂ©faut: N'Ă©coute que sur localhost) # (Mettre '0.0.0.0' pour Ă©couter partout, # MAIS activer la sĂ©curitĂ© d'abord (cf 4.2)) security: authorization: "disabled" # (DĂ©faut: Pas de mot de passe) processManagement: timeZoneInfo: /usr/share/zoneinfo
La méthode la plus simple pour le dev. docker-compose.yml (Mongo + UI Web).
version: '3.8'
services:
# 1. Service MongoDB
mongo:
image: mongo:7.0
container_name: mongo_db
ports:
- "27017:27017" # (Expose le port 27017)
volumes:
- mongo_data:/data/db
environment:
MONGO_INITDB_ROOT_USERNAME: root
MONGO_INITDB_ROOT_PASSWORD: root_password
restart: unless-stopped
# 2. Service Mongo Express (UI Web)
mongo-express:
image: mongo-express
container_name: mongo_ui
ports:
- "8081:8081"
environment:
ME_CONFIG_MONGODB_ADMINUSERNAME: root
ME_CONFIG_MONGODB_ADMINPASSWORD: root_password
ME_CONFIG_MONGODB_SERVER: mongo # (Nom du service 'mongo')
depends_on:
- mongo
restart: unless-stopped
volumes:
mongo_data:Lancez docker compose up -d.
Mongo : mongodb://root:root_password@localhost:27017
UI Web : http://localhost:8081
mongosh (CLI) & Compass (UI)mongosh (CLI)
Le shell interactif (JS) moderne de Mongo. (Remplace l'ancien mongo).
# Lancer le shell (connexion Ă localhost:27017) $ mongosh Current Mongosh Log ID: ... Connecting to: mongodb://127.0.0.1:27017/ Using MongoDB: 7.0.x ... test> # (Le prompt 'test' indique la BDD actuelle) # Changer de BDD test> use ideo_lab_db switched to db ideo_lab_db ideo_lab_db> # Lister les BDD ideo_lab_db> show dbs admin ... config ... local ... # Lister les Collections ideo_lab_db> show collections
MongoDB Compass (UI Officielle)
Compass est l'IDE/UI graphique officiel (gratuit) pour MongoDB. C'est l'équivalent de PhpMyAdmin ou DBeaver.
Fonctionnalités :
- Visualisation (CRUD) des documents (BSON/JSON).
- Création/Gestion des Index.
- Analyse (
explain()) visuelle des requĂȘtes. - Analyse du schĂ©ma (Schema Validation).
- Outil d'Aggregation Pipeline.
Hiérarchie
BDD (Database) : Un conteneur pour les collections.
Collection : Un conteneur pour les documents (équivalent d'une "table" SQL).
Document : Un objet BSON (équivalent d'une "ligne" SQL).
Création Implicite
Dans Mongo, tout est créé à la volée. Pas besoin de CREATE DATABASE ou CREATE TABLE.
# 1. Changer vers une BDD (mĂȘme si elle n'existe pas)
test> use nouvelle_db
switched to db nouvelle_db
# 2. 'nouvelle_db' n'est PAS encore créée.
# (Elle ne sera créée que lors de la 1Úre insertion)
# 3. InsĂ©rer dans une 'collection' (mĂȘme si elle n'existe pas)
nouvelle_db> db.articles.insertOne({ titre: "Test" })
# 4. MAINTENANT, 'nouvelle_db' et 'articles' existent.Création Explicite
Vous pouvez (rarement) avoir besoin de créer une collection avec des options (ex: timeseries, validation).
ideo_lab_db> db.createCollection("logs", {
timeseries: {
timeField: "timestamp"
}
})insertOne, insertMany)insertOne()
db.articles.insertOne({
titre: "Mon Article 1",
tags: ["mongo", "guide"],
auteur: { nom: "Alice" }
})
// Réponse:
{
"acknowledged" : true,
"insertedId" : ObjectId("67f51...")
}insertMany()
db.articles.insertMany([
{ _id: 10, titre: "Article 2" }, // On peut forcer l'_id
{ titre: "Article 3", status: "brouillon" }
])
// Réponse:
{
"acknowledged" : true,
"insertedIds" : [ 10, ObjectId("67f52...") ]
}find, findOne)find() (Retourne un Curseur)
// SELECT * FROM articles
db.articles.find().pretty()
// (Filtre: WHERE status = 'publie')
db.articles.find({ status: "publie" })
// (Filtre: WHERE tags = 'mongo')
db.articles.find({ tags: "mongo" })
// (Filtre: WHERE auteur.nom = 'Alice')
db.articles.find({ "auteur.nom": "Alice" })findOne() (Retourne 1 Document)
db.articles.findOne({ _id: 10 })Projection (SELECT col1, col2)
Le 2Ăšme argument de find() est la "Projection". (1 = inclure, 0 = exclure).
// N'inclure que 'titre' et 'status'
db.articles.find(
{ status: "publie" }, // Filtre
{ titre: 1, status: 1, _id: 0 } // Projection
)Options (sort, limit)
db.articles.find()
.sort({ date_pub: -1 }) // -1 = DESC, 1 = ASC
.limit(10)
.skip(20)$gt, $in, $or)Opérateurs de Comparaison
// WHERE vues > 1000
db.articles.find({ vues: { $gt: 1000 } })
// (Autres: $gte (>=), $lt (<), $lte (<=), $ne (!=))
// WHERE status IN ('publie', 'archive')
db.articles.find({ status: { $in: ["publie", "archive"] } })
// WHERE tags CONTAINS 'mongo' AND 'python'
db.articles.find({ tags: { $all: ["mongo", "python"] } })
// WHERE 'description' exists
db.articles.find({ description: { $exists: true } })Opérateurs Logiques
// WHERE (status = 'publie' OR vues > 5000)
db.articles.find({
$or: [
{ status: "publie" },
{ vues: { $gt: 5000 } }
]
})
// WHERE (status = 'publie' AND vues > 1000)
db.articles.find({
$and: [
{ status: "publie" },
{ vues: { $gt: 1000 } }
]
})
// (Note: { status: "publie", vues: { $gt: 1000 } } est plus simple)
// Regex (WHERE titre LIKE 'Mon%')
db.articles.find({ titre: { $regex: '^Mon', $options: 'i' } })$set, $inc)updateOne() / updateMany()
â ïž Attention : L'update nĂ©cessite des "opĂ©rateurs d'update" (ex: $set).
// (MAUVAIS: Ăcrase tout le document)
// db.articles.updateOne({_id: 1}, { status: "archive" })
// 1. $set (Mettre Ă jour/Ajouter un champ)
db.articles.updateOne(
{ _id: 1 }, // Filtre
{ $set: { status: "archive", "auteur.nom": "Alice V2" } }
)
// 2. $unset (Supprimer un champ)
db.articles.updateOne(
{ _id: 1 },
{ $unset: { description: "" } }
)Opérateurs (Atomiques)
// 3. $inc (Incrémenter)
db.articles.updateOne(
{ _id: 1 },
{ $inc: { vues: 1 } } // (Atomique)
)
// 4. $push (Ajouter Ă un Array)
db.articles.updateOne(
{ _id: 1 },
{ $push: { tags: "news" } }
)
// 5. $pull (Retirer d'un Array)
db.articles.updateOne(
{ _id: 1 },
{ $pull: { tags: "mongo" } }
)delete, drop)Supprimer des Documents
// Supprime UN seul document (le 1er trouvé)
db.articles.deleteOne({ status: "brouillon" })
// Supprime TOUS les documents (selon filtre)
db.articles.deleteMany({ status: "archive" })
// Supprime TOUS les documents (filtre vide)
db.articles.deleteMany({ })Supprimer (Drop)
// Supprime la collection (et les index) db.articles.drop() // Se positionner sur la BDD use ideo_lab_db // Supprime la BDD actuelle db.dropDatabase()
L'index _id (Défaut)
Par défaut, MongoDB crée un index unique sur le champ _id. Une recherche par _id est donc instantanée.
COLLSCAN (Scan de Collection)
Si vous cherchez sur un champ non-indexé (ex: titre), Mongo doit faire un COLLSCAN : il doit lire **chaque document** de la collection (lent).
IXSCAN (Scan d'Index)
Si vous créez un index sur titre, Mongo crée une structure (Arbre B+) triée. Une recherche sur titre utilise l'index (IXSCAN) et trouve le document instantanément, sans lire toute la collection.
Créer & Lister les Index
// Crée un index (Ascendant: 1) sur 'status'
db.articles.createIndex({ status: 1 })
// Crée un index (Descendant: -1) sur 'date_pub'
db.articles.createIndex({ date_pub: -1 })
// Crée un index unique
db.users.createIndex({ email: 1 }, { unique: true })
// Lister les index
db.articles.getIndexes()explain("executionStats") (Le débugger)
Permet de voir *comment* Mongo exĂ©cute la requĂȘte (utilise-t-il un index ?).
db.articles.find({ status: "publie" }).explain("executionStats")Résultat (Mauvais - COLLSCAN)
"winningPlan": {
"stage": "COLLSCAN", // (Scan de collection)
"filter": { "status": { "$eq": "publie" } }
},
"executionStats": {
"nReturned": 50,
"totalDocsExamined": 100000, // (A lu 100 000 docs !)
"executionTimeMillis": 120
}Résultat (Bon - IXSCAN) (AprÚs createIndex({ status: 1 }))
"winningPlan": {
"stage": "FETCH",
"inputStage": {
"stage": "IXSCAN", // (Scan d'Index)
"keyPattern": { "status": 1 },
}
},
"executionStats": {
"nReturned": 50,
"totalDocsExamined": 50, // (N'a lu que 50 docs !)
"executionTimeMillis": 2
}Index Composé (Compound)
Un index sur plusieurs champs (pour les requĂȘtes find+sort).
// Pour la requĂȘte:
// db.users.find({ age: { $gt: 30 } }).sort({ nom: 1 })
// On crée l'index (l'ordre compte !)
db.users.createIndex({ age: 1, nom: 1 })Index TTL (Time-To-Live)
Supprime automatiquement les documents aprĂšs X secondes. Parfait pour les logs, sessions, cache.
// Supprime les docs 1h (3600s) aprĂšs 'date_creation'
db.logs.createIndex(
{ "date_creation": 1 },
{ expireAfterSeconds: 3600 }
)Index Texte (Full-Text Search)
Permet la recherche "Google" (stop-words, stemming...).
// 1. Créer l'index (sur 'titre' et 'contenu')
db.articles.createIndex({
titre: "text",
contenu: "text"
})
// 2. Utiliser l'opérateur $text
db.articles.find({
$text: {
$search: "python guide" // (Cherche 'python' ET 'guide')
}
})Haute Disponibilité (HA)
Un "Replica Set" est un groupe (minimum 3) de serveurs mongod qui se copient les uns les autres. Le but est la **Haute Disponibilité** (failover).
Composition (P-S-A)
- 1 Primaire (Primary) : Le seul nĆud qui accepte les Ă©critures.
- 2+ Secondaires (Secondary) : Reçoivent les données (
oplog) du Primaire. Acceptent les lectures (optionnel). - (Optionnel) 1 Arbiter : Un nĆud "juge" lĂ©ger, qui ne stocke pas de donnĂ©es, mais vote en cas d'Ă©lection.
Scénario de "Failover"
(App) -> [Primaire (N1)] -> (Copie) -> [Secondaire (N2)] | | | | +---- (Copie) ------------>+ | | +<----------- (Heartbeat) ----------->+ --- (N1 CRASHE) --- (App) X [Primaire (N1)] (Timeout) [Secondaire (N2)] | | | (Ălection: N2 devient Primaire) | | | (App) ---------------------------------> [Nouveau Primaire (N2)]
1. /etc/mongod.conf (Sur *tous* les nĆuds)
Vous devez configurer le nom du Replica Set et l'écoute réseau (pas 127.0.0.1).
net: port: 27017 bindIp: 0.0.0.0 # (Ăcoute partout, sĂ©curiser avec firewall) replication: replSetName: "rs0" # (Nom de votre Replica Set)
(RedĂ©marrez mongod sur tous les nĆuds).
2. Initialisation (Sur 1 seul nĆud)
# 1. Se connecter au 1er nĆud
$ mongosh
# 2. Définir la configuration
> config = {
_id: "rs0",
members: [
{ _id: 0, host: "10.0.0.1:27017" },
{ _id: 1, host: "10.0.0.2:27017" },
{ _id: 2, host: "10.0.0.3:27017" }
]
}
# 3. Initialiser le Replica Set
> rs.initiate(config)
# 4. Vérifier
rs0:PRIMARY> rs.status()
# 5. (Optionnel) Ajouter un Arbiter
rs0:PRIMARY> rs.addArb("10.0.0.4:27017")$group)Le "Query Builder" de MongoDB. Il permet de faire des opérations complexes (type GROUP BY SQL) en passant les documents à travers un "Pipeline" d'étapes (stages).
Pipeline (Exemple)
Objectif : Calculer le CA total par 'tag' (uniquement pour les articles 'publie').
db.articles.aggregate([
// Stage 1: (WHERE) Filtrer les documents
{
$match: { status: "publie" }
},
// Stage 2: (UNWIND) "Dénormaliser" l'array
{
$unwind: "$tags" // {tags: [a,b]} -> {tags: a}, {tags: b}
},
// Stage 3: (GROUP BY) Grouper par tag
{
$group: {
_id: "$tags", // (Le 'GROUP BY tags')
totalVues: { $sum: "$vues" },
avgVues: { $avg: "$vues" },
count: { $sum: 1 }
}
},
// Stage 4: (ORDER BY)
{
$sort: { totalVues: -1 }
}
])1. Activer l'Authentification (mongod.conf)
Par défaut, Mongo n'a pas d'authentification. Il faut l'activer.
# /etc/mongod.conf security: authorization: "enabled"
sudo systemctl restart mongod
â ïž Attention : Ne *jamais* activer cela sans avoir créé un utilisateur Admin (sinon vous ĂȘtes bloquĂ© dehors).
2. Créer un Utilisateur (RBAC)
Mongo utilise le RBAC (Role-Based Access Control).
# (Doit ĂȘtre fait AVANT d'activer l'auth)
$ mongosh
# 1. Se mettre sur la BDD 'admin'
> use admin
# 2. Créer l'Admin du cluster
> db.createUser({
user: "clusterAdmin",
pwd: passwordPrompt(), // (Demande le mot de passe)
roles: [ { role: "root", db: "admin" } ]
})
# 3. Créer un User applicatif
> use ideo_lab_db
> db.createUser({
user: "djongo_user",
pwd: passwordPrompt(),
roles: [ { role: "readWrite", db: "ideo_lab_db" } ]
})
# (AprÚs redémarrage avec 'authorization: "enabled"')
$ mongosh -u clusterAdmin -p --authenticationDatabase="admin"
> use ideo_lab_db
> db.auth("djongo_user", passwordPrompt())1. explain("executionStats")
L'outil n°1. Montre si une requĂȘte utilise un index (IXSCAN) ou un scan de collection (COLLSCAN). (Voir 3.2).
2. Outils CLI
# (Similaire Ă 'top') # Moniteur en temps rĂ©el (Read/Write, ms) mongotop # (Similaire Ă 'vmstat') # Stats globales (connexions, requĂȘtes/sec, faults) mongostat
3. Tuning (mongod.conf)
WiredTiger (Moteur de stockage) :
Par défaut, WiredTiger utilise 50% de la RAM ((RAM - 1GB) / 2) pour son cache interne.
# /etc/mongod.conf
storage:
wiredTiger:
engineConfig:
# Augmenter le cache (ex: 8GB)
cacheSizeGB: 8Tuning (Linux) :
Désactiver THP (Transparent Huge Pages) et augmenter ulimit (fichiers ouverts) sont des optimisations courantes.
Djongo (Traducteur SQL -> Mongo)
ProblĂšme : Django est un ORM SQL. MongoDB est NoSQL. Ils sont incompatibles.
Solution : djongo. Un "fork" de Django qui traduit les requĂȘtes de l'ORM Django (SQL-like) en requĂȘtes MongoDB (JSON).
â ïž Attention : djongo peut ĂȘtre instable et n'est pas toujours Ă jour avec les derniĂšres versions de Django. (django-mongoengine est l'alternative, mais n'est *pas* l'ORM Django).
Installation
(venv) $ pip install djongo
settings.py (DATABASES)
Remplacez la configuration DATABASES.
DATABASES = {
'default': {
'ENGINE': 'djongo',
'NAME': 'ideo_lab_django', // Nom de la BDD Mongo
'CLIENT': {
'host': '127.0.0.1',
'port': 27017,
'username': 'djongo_user', // (Si auth activée)
'password': 'password',
'authSource': 'ideo_lab_django',
}
}
}
# (Désactiver les 'related_field' non-supportés)
SILENCED_SYSTEM_CHECKS = ["fields.E300", "fields.E307"]Vous pouvez ensuite utiliser makemigrations, migrate, et l'Admin Django (presque) normalement.
mongosh)Navigation
mongosh show dbs use ideo_lab_db show collections db.stats() db.collection.stats()
CRUD (Create, Read)
db.articles.insertOne({ ... })
db.articles.insertMany([ ... ])
db.articles.find().pretty()
db.articles.findOne({ _id: 1 })
db.articles.find({ status: "publie" })
db.articles.find({ vues: { $gt: 100 } })
db.articles.find({ $or: [ ... ] })
db.articles.find().sort({ date: -1 }).limit(5)CRUD (Update, Delete)
db.articles.updateOne(
{ _id: 1 },
{ $set: { status: "archive" } }
)
db.articles.updateMany(
{ status: "draft" },
{ $set: { status: "archive" } }
)
db.articles.updateOne(
{ _id: 1 },
{ $inc: { vues: 1 } }
)
db.articles.deleteOne({ _id: 1 })
db.articles.deleteMany({ status: "archive" })
db.articles.drop() # Supprime la collection
db.dropDatabase() # Supprime la BDD