Tri MongoDB
Apprenez à trier les résultats de requêtes MongoDB en Python avec la méthode sort() de PyMongo — ordre croissant, décroissant, multi-clés, avec limit et filtre.
Ce chapitre explique comment trier les résultats de requêtes MongoDB en Python à l'aide du pilote pymongo. Vous apprendrez à trier sur un seul champ en ordre croissant ou décroissant, à trier sur plusieurs champs simultanément, à combiner le tri avec le filtrage et la limitation, et à comprendre quand un index rend le tri rapide.
Prérequis
Vous devez être familier avec la connexion à MongoDB et l'interrogation de documents. Si vous ne l'avez pas encore fait, lisez d'abord MongoDB Find et MongoDB Query.
Les exemples ci-dessous supposent une collection appelée products dans une base de données appelée store. Vous pouvez insérer les documents exemples utilisés tout au long de cette page avec :
import pymongo
client = pymongo.MongoClient("mongodb://localhost:27017/")
db = client["store"]
col = db["products"]
# Insert sample data (skip if already inserted)
col.drop()
col.insert_many([
{"name": "Keyboard", "category": "Electronics", "price": 49.99, "stock": 120},
{"name": "Mouse", "category": "Electronics", "price": 29.99, "stock": 85},
{"name": "Desk", "category": "Furniture", "price": 249.99, "stock": 30},
{"name": "Chair", "category": "Furniture", "price": 189.99, "stock": 45},
{"name": "Monitor", "category": "Electronics", "price": 319.99, "stock": 60},
{"name": "Lamp", "category": "Furniture", "price": 39.99, "stock": 200},
])
print("Sample data inserted.")La méthode sort()
La méthode sort() est appelée sur un curseur (l'objet retourné par find()) et indique à MongoDB dans quel ordre retourner les documents. Sa signature est :
cursor.sort(key_or_list, direction=None)key_or_list— un nom de champ (string) lors d'un tri sur un seul champ, ou une liste de tuples(field, direction)lors d'un tri sur plusieurs champs.direction—pymongo.ASCENDING(valeur1) oupymongo.DESCENDING(valeur-1). Requis lorsquekey_or_listest une string simple ; à omettre avec la forme liste.
Utiliser les constantes nommées (pymongo.ASCENDING / pymongo.DESCENDING) plutôt que des entiers bruts rend le code plus lisible et évite les erreurs de valeur.
Tri en ordre croissant
Passez pymongo.ASCENDING comme second argument pour trier de la valeur la plus basse à la plus haute :
import pymongo
client = pymongo.MongoClient("mongodb://localhost:27017/")
db = client["store"]
col = db["products"]
results = col.find({}, {"_id": 0, "name": 1, "price": 1}).sort("price", pymongo.ASCENDING)
for doc in results:
print(doc)Résultat attendu (le moins cher en premier) :
{'name': 'Mouse', 'price': 29.99}
{'name': 'Lamp', 'price': 39.99}
{'name': 'Keyboard', 'price': 49.99}
{'name': 'Chair', 'price': 189.99}
{'name': 'Desk', 'price': 249.99}
{'name': 'Monitor', 'price': 319.99}La projection {"_id": 0, "name": 1, "price": 1} limite les champs retournés à name et price, ce qui rend la sortie plus concise. Les projections sont abordées dans MongoDB Find.
Tri en ordre décroissant
Passez pymongo.DESCENDING pour inverser l'ordre (de la valeur la plus haute à la plus basse) :
import pymongo
client = pymongo.MongoClient("mongodb://localhost:27017/")
db = client["store"]
col = db["products"]
results = col.find({}, {"_id": 0, "name": 1, "price": 1}).sort("price", pymongo.DESCENDING)
for doc in results:
print(doc)Résultat attendu (le plus cher en premier) :
{'name': 'Monitor', 'price': 319.99}
{'name': 'Desk', 'price': 249.99}
{'name': 'Chair', 'price': 189.99}
{'name': 'Keyboard', 'price': 49.99}
{'name': 'Lamp', 'price': 39.99}
{'name': 'Mouse', 'price': 29.99}Tri sur plusieurs champs
Lorsque vous souhaitez trier par plus d'un champ — par exemple, par catégorie d'abord, puis par prix au sein de chaque catégorie — passez une liste de tuples (field, direction) :
import pymongo
client = pymongo.MongoClient("mongodb://localhost:27017/")
db = client["store"]
col = db["products"]
results = col.find({}, {"_id": 0, "name": 1, "category": 1, "price": 1}).sort([
("category", pymongo.ASCENDING),
("price", pymongo.ASCENDING),
])
for doc in results:
print(doc)Résultat attendu (catégories de A à Z, le moins cher en premier dans chaque catégorie) :
{'name': 'Mouse', 'category': 'Electronics', 'price': 29.99}
{'name': 'Keyboard', 'category': 'Electronics', 'price': 49.99}
{'name': 'Monitor', 'category': 'Electronics', 'price': 319.99}
{'name': 'Lamp', 'category': 'Furniture', 'price': 39.99}
{'name': 'Chair', 'category': 'Furniture', 'price': 189.99}
{'name': 'Desk', 'category': 'Furniture', 'price': 249.99}Les champs de tri sont appliqués de gauche à droite : MongoDB trie d'abord tous les documents par category, puis départage les ex-æquo au sein de la même valeur de catégorie par price.
Combiner sort() avec le filtrage
sort() fonctionne avec n'importe quel filtre de requête. Le filtre sélectionne les documents correspondants ; sort() ordonne ensuite uniquement ces documents filtrés :
import pymongo
client = pymongo.MongoClient("mongodb://localhost:27017/")
db = client["store"]
col = db["products"]
# Find Electronics only, sorted cheapest first
query = {"category": "Electronics"}
fields = {"_id": 0, "name": 1, "price": 1}
results = col.find(query, fields).sort("price", pymongo.ASCENDING)
for doc in results:
print(doc)Résultat attendu :
{'name': 'Mouse', 'price': 29.99}
{'name': 'Keyboard', 'price': 49.99}
{'name': 'Monitor', 'price': 319.99}Consultez MongoDB Query pour plus d'options de filtrage telles que les requêtes de plage ($gt, $lt) et la correspondance de motifs.
Combiner sort() avec limit()
Enchaînez limit() après sort() pour obtenir les N premiers (ou derniers) documents. L'ordre de chaînage n'a pas d'importance — MongoDB applique toujours le tri avant la limitation :
import pymongo
client = pymongo.MongoClient("mongodb://localhost:27017/")
db = client["store"]
col = db["products"]
# Top 3 most expensive products
results = col.find({}, {"_id": 0, "name": 1, "price": 1}) \
.sort("price", pymongo.DESCENDING) \
.limit(3)
for doc in results:
print(doc)Résultat attendu :
{'name': 'Monitor', 'price': 319.99}
{'name': 'Desk', 'price': 249.99}
{'name': 'Chair', 'price': 189.99}Lisez MongoDB Limit pour en savoir plus sur le contrôle du nombre de documents retournés.
Performance : utiliser un index pour les grandes collections
Pour les petites collections, MongoDB trie les résultats en mémoire. Sur une grande collection, un tri en mémoire peut être lent et — s'il dépasse 100 Mo — MongoDB retournera une erreur. Créer un index sur le champ de tri permet à MongoDB de retourner des données pré-triées sans parcourir toute la collection :
import pymongo
client = pymongo.MongoClient("mongodb://localhost:27017/")
db = client["store"]
col = db["products"]
# Create a single-field index on price (ascending)
col.create_index([("price", pymongo.ASCENDING)])
# Queries that sort by price now use the index automatically
results = col.find({}, {"_id": 0, "name": 1, "price": 1}).sort("price", pymongo.ASCENDING)
for doc in results:
print(doc)Pour les tris multi-champs, créez un index composé dont les champs et les directions correspondent à votre tri :
col.create_index([
("category", pymongo.ASCENDING),
("price", pymongo.ASCENDING),
])Vous n'avez besoin de créer chaque index qu'une seule fois. Les appels répétés à create_index() avec la même clé sont sans danger — PyMongo vérifie si l'index existe déjà.
Stocker la chaîne de connexion en toute sécurité
Les exemples ci-dessus codent en dur la chaîne de connexion par souci de simplicité. Dans une application réelle, stockez-la dans une variable d'environnement :
import os
import pymongo
client = pymongo.MongoClient(os.environ["MONGODB_URI"])Définissez la variable dans votre shell (export MONGODB_URI="mongodb://localhost:27017/") ou utilisez un fichier .env avec une bibliothèque telle que python-dotenv.
Résumé
| Objectif | Modèle de code |
|---|---|
| Tri croissant | .sort("field", pymongo.ASCENDING) |
| Tri décroissant | .sort("field", pymongo.DESCENDING) |
| Tri sur plusieurs champs | .sort([("f1", pymongo.ASCENDING), ("f2", pymongo.DESCENDING)]) |
| N premiers résultats | .sort(...).limit(N) |
| Tri rapide sur de grandes données | Créer un index sur le champ de tri |
Chapitres connexes de cette série :
- MongoDB Find — récupération de documents avec
find()etfind_one() - MongoDB Query — filtrage avec les opérateurs de requête
- MongoDB Limit — contrôle du nombre de documents retournés
- MongoDB Update — modification de documents dans une collection