Premiers pas avec MongoDB
Apprenez à installer MongoDB, vous connecter avec PyMongo et effectuer des opérations CRUD de base en Python avec des exemples concrets.
Ce chapitre présente MongoDB et vous montre comment l'utiliser depuis Python grâce au driver PyMongo. À la fin de ce chapitre, vous aurez installé MongoDB, établi une connexion fonctionnelle et obtenu une vue d'ensemble claire sur la façon d'insérer, d'interroger, de mettre à jour et de supprimer des documents.
Qu'est-ce que MongoDB ?
MongoDB est une base de données documentaire — un type de base de données NoSQL qui stocke les enregistrements sous forme de documents JSON-like plutôt que de lignes et de colonnes. Chaque document est un objet autonome qui peut contenir des champs imbriqués et des arrays, ce qui en fait une solution naturellement adaptée aux données qui ne s'intègrent pas aisément dans un schéma fixe.
Caractéristiques principales :
- Schéma flexible. Deux documents d'une même collection peuvent avoir des champs complètement différents.
- Langage de requête riche. Filtrez, projetez, triez, limitez et agrégez en un seul appel au driver.
- Scalabilité horizontale. Le sharding intégré et les replica sets gèrent de grands volumes de données et une haute disponibilité.
- Natif JSON. Les documents sont stockés en BSON (Binary JSON), de sorte que les dictionnaires Python correspondent directement aux documents MongoDB.
Quand choisir MongoDB plutôt qu'une base de données relationnelle
| Situation | Bon choix ? |
|---|---|
| Structure des données changeant rapidement (prototypes, API) | Oui |
| Données hiérarchiques / imbriquées | Oui |
Requêtes complexes avec plusieurs JOIN | Préférer SQL |
Transactions ACID strictes sur plusieurs tables | Préférer SQL |
| Recherche plein texte à grande échelle | Combiner avec Elasticsearch |
Installer MongoDB
Option 1 — Installation locale
Téléchargez le MongoDB Community Server depuis mongodb.com/try/download/community, choisissez votre système d'exploitation et suivez l'installeur. Démarrez ensuite le serveur :
# macOS / Linux
mongod --dbpath /data/db
# Windows (PowerShell, run as Administrator)
mongod --dbpath "C:\data\db"Vérifiez que MongoDB fonctionne en ouvrant un second terminal et en exécutant :
mongosh --eval "db.adminCommand('ping')"Sortie attendue :
{ ok: 1 }Option 2 — Docker (le plus rapide pour le développement)
Si Docker est installé, vous pouvez ignorer l'installation locale :
docker run -d --name mongo -p 27017:27017 mongo:7Cela télécharge l'image officielle MongoDB 7 et expose le port 27017 sur votre machine. Arrêtez-la avec docker stop mongo.
Option 3 — MongoDB Atlas (cloud)
Atlas est le service cloud entièrement géré de MongoDB avec un niveau gratuit. Après l'inscription, copiez la chaîne de connexion depuis le tableau de bord — elle ressemble à ceci :
mongodb+srv://username:[email protected]/Vous pouvez utiliser cette URI partout où vous voyez mongodb://localhost:27017/ dans ce chapitre.
Installer le driver PyMongo
PyMongo est le driver Python officiel pour MongoDB. Installez-le avec pip :
pip install pymongoPour utiliser MongoDB Atlas, installez également les extras incluant le résolveur DNS :
pip install "pymongo[srv]"Vérifiez l'installation :
import pymongo
print(pymongo.version)
# e.g. 4.7.3Se connecter à MongoDB
MongoClient est le point d'entrée de toutes les opérations du driver. Créez un seul client par application et réutilisez-le — le client gère un pool de connexions interne.
from pymongo import MongoClient
# Local server with default host and port
client = MongoClient("mongodb://localhost:27017/")
# Verify connectivity (raises ConnectionFailure if the server is unreachable)
client.admin.command("ping")
print("Connected successfully")Pour le code en production, gérez toujours les erreurs de connexion de manière explicite :
from pymongo import MongoClient
from pymongo.errors import ConnectionFailure
client = MongoClient("mongodb://localhost:27017/", serverSelectionTimeoutMS=3000)
try:
client.admin.command("ping")
print("Connected to MongoDB")
except ConnectionFailure as e:
print("Connection failed:", e)Format de la chaîne de connexion
mongodb://[username:password@]host[:port][/database][?options]Options courantes :
| Option | Exemple | Utilité |
|---|---|---|
authSource | authSource=admin | Base de données utilisée pour l'authentification |
replicaSet | replicaSet=rs0 | Connexion à un replica set |
tls=true | tls=true | Activer TLS/SSL |
serverSelectionTimeoutMS | serverSelectionTimeoutMS=5000 | Délai d'attente pour la sélection du serveur |
Bases de données et collections
MongoDB organise les données selon une hiérarchie à deux niveaux :
- Une base de données regroupe des collections associées (similaire à un schéma ou une base de données SQL).
- Une collection contient des documents (similaire à une table SQL, mais sans schéma fixe).
Les deux sont créées de façon paresseuse — elles sont instanciées la première fois que vous insérez un document. Vous n'exécutez jamais CREATE DATABASE ni CREATE TABLE.
from pymongo import MongoClient
client = MongoClient("mongodb://localhost:27017/")
# Reference a database (not yet created on disk)
db = client["mystore"]
# Reference a collection inside it (also not yet on disk)
products = db["products"]
# The database and collection are created when the first document is insertedOpérations CRUD de base
Les exemples suivants s'enchaînent les uns avec les autres. Exécutez-les dans l'ordre si vous suivez ce tutoriel de manière interactive.
Créer — insérer des documents
Utilisez insert_one() pour un seul document et insert_many() pour un lot :
from pymongo import MongoClient
client = MongoClient("mongodb://localhost:27017/")
db = client["mystore"]
products = db["products"]
# Insert a single document
result = products.insert_one({
"name": "Laptop",
"brand": "Acme",
"price": 999.99,
"in_stock": True
})
print("Inserted id:", result.inserted_id)
# Insert multiple documents at once
new_products = [
{"name": "Mouse", "brand": "Acme", "price": 29.99, "in_stock": True},
{"name": "Keyboard", "brand": "Acme", "price": 79.99, "in_stock": False},
{"name": "Monitor", "brand": "Zeta", "price": 349.99, "in_stock": True},
]
batch_result = products.insert_many(new_products)
print("Inserted ids:", batch_result.inserted_ids)MongoDB ajoute automatiquement un champ _id (de type ObjectId) à chaque document si vous n'en fournissez pas. Ce champ est la clé primaire et est toujours unique au sein d'une collection.
Lire — interroger des documents
find_one() renvoie le premier document correspondant (ou None). find() renvoie un curseur que vous pouvez parcourir.
# Retrieve one document (no filter = the first document in natural order)
doc = products.find_one()
print(doc)
# Retrieve all documents in the collection
for p in products.find():
print(p["name"], "-", p["price"])
# Filter: products that are in stock
for p in products.find({"in_stock": True}):
print(p["name"])
# Projection: return only name and price (exclude _id)
for p in products.find({}, {"_id": 0, "name": 1, "price": 1}):
print(p)Opérateurs de requête
Le langage de requête de MongoDB utilise des opérateurs préfixés par $ :
# Products cheaper than £100
cheap = products.find({"price": {"$lt": 100}})
# In-stock products from brand "Acme" or "Zeta"
multi = products.find({
"in_stock": True,
"brand": {"$in": ["Acme", "Zeta"]}
})
# Price between 50 and 500 (inclusive)
range_q = products.find({"price": {"$gte": 50, "$lte": 500}})Opérateurs de comparaison courants :
| Opérateur | Signification |
|---|---|
$eq | Égal (par défaut avec {"field": value}) |
$ne | Différent |
$gt / $gte | Supérieur à / supérieur ou égal à |
$lt / $lte | Inférieur à / inférieur ou égal à |
$in | La valeur est dans une liste |
$nin | La valeur n'est pas dans une liste |
Mettre à jour — modifier des documents
update_one() modifie le premier document correspondant. update_many() modifie tous les documents correspondants. Utilisez toujours l'opérateur $set pour modifier des champs spécifiques — sans lui, vous remplacez le document entier.
# Update a single document: change the price of "Mouse"
update_result = products.update_one(
{"name": "Mouse"}, # filter
{"$set": {"price": 24.99}} # update
)
print("Matched:", update_result.matched_count,
"Modified:", update_result.modified_count)
# Mark all Acme products as in stock
products.update_many(
{"brand": "Acme"},
{"$set": {"in_stock": True}}
)
# Increment a field value
products.update_one(
{"name": "Laptop"},
{"$inc": {"price": -50}} # reduce price by 50
)Opérateurs de mise à jour courants :
| Opérateur | Effet |
|---|---|
$set | Définit un ou plusieurs champs |
$unset | Supprime un champ |
$inc | Incrémente un champ numérique |
$push | Ajoute une valeur à un champ de type array |
$pull | Retire une valeur d'un champ de type array |
Supprimer — enlever des documents
delete_one() supprime le premier document correspondant. delete_many() supprime tous les documents correspondants.
# Remove a single document
del_result = products.delete_one({"name": "Keyboard"})
print("Deleted count:", del_result.deleted_count)
# Remove all out-of-stock items
products.delete_many({"in_stock": False})
# Confirm what is left
print("Remaining products:")
for p in products.find({}, {"_id": 0, "name": 1}):
print(" -", p["name"])Pièges courants
La création paresseuse peut masquer les fautes de frappe
Comme MongoDB crée les bases de données et les collections à la demande, une faute de frappe crée silencieusement une seconde base de données vide au lieu de générer une erreur :
# Intended: client["mystore"] Actual: client["mystoree"]
db = client["mystoree"] # no error, but your data goes to the wrong databaseSolution : définissez les noms de base de données et de collection comme des constantes au niveau du module :
DB_NAME = "mystore"
COL_NAME = "products"
db = client[DB_NAME]
products = db[COL_NAME]Les erreurs de connexion n'apparaissent qu'à la première opération
MongoClient() réussit même quand MongoDB n'est pas en cours d'exécution. L'erreur n'apparaît que lors d'une vraie requête. Utilisez serverSelectionTimeoutMS et un test ping au démarrage (comme indiqué dans la section connexion ci-dessus) pour détecter les problèmes rapidement.
L'absence de $set remplace le document entier
# WRONG — replaces the whole document with just {"price": 24.99}
products.update_one({"name": "Mouse"}, {"price": 24.99})
# CORRECT — only changes the price field
products.update_one({"name": "Mouse"}, {"$set": {"price": 24.99}})find() renvoie un curseur, pas une liste
Un curseur est paresseux — les documents sont récupérés depuis le serveur uniquement lorsque vous les parcourez. Si vous avez besoin d'une liste simple, convertissez-le explicitement :
all_products = list(products.find())Soyez prudent avec les grandes collections : tout charger en mémoire d'un coup peut épuiser la RAM.
La suite
Ce chapitre a couvert l'essentiel. Le reste de la série Python MongoDB approfondit chaque sujet :
- MongoDB Create Database — comment fonctionne la création paresseuse et comment vérifier qu'une base de données existe.
- MongoDB Create Collection — options de création de collection et schémas de validation.
- MongoDB Insert —
insert_one(),insert_many()et la gestion des erreurs de clé dupliquée. - MongoDB Find — projections, curseurs et tri.
- MongoDB Query — référence complète des opérateurs de requête.
- MongoDB Update —
update_one(),update_many(),upsertet opérateurs d'array. - MongoDB Delete — modèles de suppression sécurisés et
drop(). - MongoDB Sort — tri sur un ou plusieurs champs.
- MongoDB Limit — pagination avec
limit()etskip(). - MongoDB Drop Collection — suppression complète d'une collection.