W3docs

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.
  • directionpymongo.ASCENDING (valeur 1) ou pymongo.DESCENDING (valeur -1). Requis lorsque key_or_list est 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é

ObjectifModè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éesCréer un index sur le champ de tri

Chapitres connexes de cette série :

Was this page helpful?