🗄️ Bases de données

database-mongodb-guide

Modélisation et requêtes MongoDB.

⚡ Installation & lancement en 1 commande

Copiez-collez dans votre terminal : le skill s'installe dans ~/.claude/skills et Claude Code se lance directement dessus.

macOS / Linux
curl -fsSL https://raw.githubusercontent.com/khalilbenaz/claude-skills-collection/main/install.sh | sh -s -- database-mongodb-guide --launch
Windows (PowerShell)
iex "& { $(iwr -useb https://raw.githubusercontent.com/khalilbenaz/claude-skills-collection/main/install.ps1) } database-mongodb-guide -Launch"

🚀 Déjà installé ?

claude "/database-mongodb-guide"

Ou tapez /database-mongodb-guide dans une session Claude Code, ou décrivez simplement votre besoin — le skill se déclenche automatiquement via le skill-router.

🔑 Déclencheurs automatiques

Le skill s'active automatiquement quand votre demande contient :

MongoDBMongoNoSQLaggregation pipelinesharding

📦 Installation manuelle

git clone https://github.com/khalilbenaz/claude-skills-collection.git cp -r claude-skills-collection/skills/database-mongodb-guide ~/.claude/skills/

Payload du plugin : skills/database-mongodb-guide · source éditable : database-skills/mongodb-guide

📖 Manuel

MongoDB Guide

Workflow

1. Analyser les patterns d'accès

Avant tout schéma, lister les requêtes réelles : quelles entités sont lues ensemble ? À quelle fréquence ? Ratio lecture/écriture ?

Critères de décision embed vs reference :

CritèreEmbedReference
Données toujours lues ensemble
Taille du tableau bornée (<100 éléments)
Données partagées entre plusieurs parents
Mise à jour fréquente de sous-documents
Document proche de 16 Mo

2. Concevoir le schéma

Patterns courants :

Exemple schéma Computed (compteur dénormalisé) :

// À l'écriture d'un avis :
db.products.updateOne(
  { _id: productId },
  {
    $push: { latestReviews: { $each: [review], $slice: -10 } },
    $inc: { reviewCount: 1, ratingSum: review.rating }
  }
)
// reviewCount et ratingSum toujours à jour, aucun $lookup nécessaire

3. Construire les aggregation pipelines

Règles d'ordre obligatoires :

  1. $match le plus tôt possible (utilise les index)
  2. $project / $unset pour réduire la taille des documents en transit
  3. $sort + $limit avant $lookup pour limiter les jointures
db.orders.aggregate([
  { $match: { status: "shipped", createdAt: { $gte: ISODate("2026-01-01") } } },
  { $project: { customerId: 1, totalAmount: 1, _id: 0 } },
  { $group: { _id: "$customerId", totalSpent: { $sum: "$totalAmount" } } },
  { $sort: { totalSpent: -1 } },
  { $limit: 20 },
  { $lookup: {
      from: "customers",
      localField: "_id",
      foreignField: "_id",
      as: "customer",
      pipeline: [{ $project: { name: 1, email: 1 } }]
  }},
  { $unwind: "$customer" }
])

Stages utiles souvent oubliés :

4. Créer les index (règle ESR)

Construire les index composés dans l'ordre Equality → Sort → Range :

// Requête : status = "active" AND createdAt >= X ORDER BY score DESC
db.users.createIndex({ status: 1, score: -1, createdAt: 1 })
//                     ^Equality   ^Sort       ^Range

Types d'index et cas d'usage :

// Multikey (tableau) — index sur chaque élément du tableau
db.products.createIndex({ tags: 1 })

// Text — recherche full-text avec scoring
db.articles.createIndex({ title: "text", body: "text" }, { weights: { title: 3 } })

// Partiel — indexer uniquement un sous-ensemble de documents
db.orders.createIndex({ userId: 1 }, { partialFilterExpression: { status: "active" } })

// TTL — suppression automatique après expiration
db.sessions.createIndex({ expiresAt: 1 }, { expireAfterSeconds: 0 })

// Wildcard — champs dynamiques inconnus
db.metrics.createIndex({ "attributes.$**": 1 })

Valider avant déploiement :

db.orders.find({ status: "shipped" }).explain("executionStats")
// Vérifier : IXSCAN (pas COLLSCAN), totalDocsExamined ≈ nReturned

5. Configurer le replica set

// Initialisation
rs.initiate({
  _id: "rs0",
  members: [
    { _id: 0, host: "mongo1:27017", priority: 2 },
    { _id: 1, host: "mongo2:27017", priority: 1 },
    { _id: 2, host: "mongo3:27017", priority: 0, hidden: true, votes: 1 }
  ]
})

// Lecture depuis les secondaires (lecture éventuelle acceptable)
db.getMongo().setReadPref("secondaryPreferred")

// Write concern fort pour données critiques
db.orders.insertOne(doc, { writeConcern: { w: "majority", wtimeout: 5000 } })

6. Configurer le sharding

Critères pour la shard key :

// Activer le sharding sur une base
sh.enableSharding("mydb")

// Shard key composée (userId + timestamp) — bonne distribution + requêtes ciblées
sh.shardCollection("mydb.events", { userId: 1, createdAt: 1 })

// Vérifier la distribution des chunks
db.adminCommand({ listShards: 1 })
sh.status()

7. Monitorer et diagnostiquer

# Opérations en cours et verrous
mongosh --eval "db.currentOp({ active: true, secs_running: { \$gt: 5 } })"

# Statistiques temps réel
mongostat --uri "mongodb://user:pass@host:27017"
mongotop --uri "mongodb://user:pass@host:27017" 10

# Activer le profiler (level 2 = toutes les ops, 1 = slow queries)
db.setProfilingLevel(1, { slowms: 100 })
db.system.profile.find().sort({ ts: -1 }).limit(5).pretty()

Garde-fous et anti-patterns

Pièges fréquents :

// Schema validation — exemple
db.createCollection("users", {
  validator: {
    $jsonSchema: {
      bsonType: "object",
      required: ["email", "createdAt"],
      properties: {
        email: { bsonType: "string", pattern: "^.+@.+$" },
        createdAt: { bsonType: "date" }
      }
    }
  },
  validationAction: "error"
})

Bonnes pratiques 2026