W3docs

Ordinamento MongoDB

Scopri come ordinare i risultati delle query MongoDB in Python con il metodo sort() di PyMongo — ascendente, discendente, multi-chiave, con limit e filtri.

Questo capitolo spiega come ordinare i risultati delle query MongoDB in Python utilizzando il driver pymongo. Imparerai a ordinare su un singolo campo in modo ascendente o discendente, ordinare su più campi contemporaneamente, combinare l'ordinamento con il filtraggio e la limitazione, e capire quando un indice rende l'ordinamento efficiente.

Prerequisiti

Dovresti avere familiarità con la connessione a MongoDB e l'esecuzione di query sui documenti. Se non l'hai ancora fatto, leggi prima MongoDB Find e MongoDB Query.

Gli esempi seguenti presuppongono una collezione chiamata products in un database chiamato store. Puoi inserire i documenti di esempio utilizzati in questa pagina con:

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.")

Il Metodo sort()

Il metodo sort() viene chiamato su un cursore (l'oggetto restituito da find()) e indica a MongoDB in quale ordine restituire i documenti. La sua firma è:

cursor.sort(key_or_list, direction=None)
  • key_or_list — il nome di un campo (string) quando si ordina su un singolo campo, oppure una lista di tuple (field, direction) quando si ordina su più campi.
  • directionpymongo.ASCENDING (valore 1) o pymongo.DESCENDING (valore -1). Obbligatorio quando key_or_list è una string semplice; omettilo quando si usa la forma lista.

Usare le costanti con nome (pymongo.ASCENDING / pymongo.DESCENDING) invece di interi grezzi rende il codice più leggibile ed evita errori di valore.

Ordinamento in Senso Ascendente

Passa pymongo.ASCENDING come secondo argomento per ordinare dal valore più basso al più alto:

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)

Output atteso (dal più economico):

{'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 proiezione {"_id": 0, "name": 1, "price": 1} limita i campi restituiti a name e price, mantenendo l'output conciso. Le proiezioni sono trattate in MongoDB Find.

Ordinamento in Senso Discendente

Passa pymongo.DESCENDING per invertire l'ordine (dal più alto al più basso):

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)

Output atteso (dal più costoso):

{'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}

Ordinamento su Più Campi

Quando vuoi ordinare per più di un campo — ad esempio, per categoria prima e poi per prezzo all'interno di ciascuna categoria — passa una lista di tuple (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)

Output atteso (categorie dalla A alla Z, dal più economico all'interno di ogni categoria):

{'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}

I campi di ordinamento vengono applicati da sinistra a destra: MongoDB ordina prima tutti i documenti per category, poi risolve i pareggi all'interno dello stesso valore di categoria tramite price.

Combinare sort() con il Filtraggio

sort() funziona con qualsiasi filtro di query. Il filtro seleziona i documenti corrispondenti; sort() ordina poi solo quei documenti trovati:

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)

Output atteso:

{'name': 'Mouse', 'price': 29.99}
{'name': 'Keyboard', 'price': 49.99}
{'name': 'Monitor', 'price': 319.99}

Consulta MongoDB Query per ulteriori opzioni di filtraggio come le query per intervallo ($gt, $lt) e la corrispondenza di pattern.

Combinare sort() con limit()

Concatena limit() dopo sort() per ottenere i primi (o gli ultimi) N documenti. L'ordine di concatenazione non è rilevante — MongoDB applica sempre l'ordinamento prima del limite:

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)

Output atteso:

{'name': 'Monitor', 'price': 319.99}
{'name': 'Desk', 'price': 249.99}
{'name': 'Chair', 'price': 189.99}

Leggi MongoDB Limit per ulteriori informazioni sul controllo del numero di documenti restituiti.

Prestazioni: Usa un Indice per Collezioni di Grandi Dimensioni

Per piccole collezioni, MongoDB ordina i risultati in memoria. Su una collezione di grandi dimensioni, un ordinamento in memoria può essere lento e — se supera i 100 MB — MongoDB restituirà un errore. Creare un indice sul campo di ordinamento consente a MongoDB di restituire dati pre-ordinati senza dover scansionare l'intera collezione:

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)

Per ordinamenti su più campi, crea un indice composto i cui campi e direzioni corrispondano al tuo ordinamento:

col.create_index([
    ("category", pymongo.ASCENDING),
    ("price",    pymongo.ASCENDING),
])

Devi creare ogni indice una sola volta. Le chiamate ripetute a create_index() con la stessa chiave sono sicure — PyMongo verifica se l'indice esiste già.

Archiviare la Stringa di Connessione in Modo Sicuro

Gli esempi precedenti incorporano la stringa di connessione nel codice per semplicità. In un'applicazione reale, conservala in una variabile d'ambiente:

import os
import pymongo

client = pymongo.MongoClient(os.environ["MONGODB_URI"])

Imposta la variabile nella tua shell (export MONGODB_URI="mongodb://localhost:27017/") oppure utilizza un file .env con una libreria come python-dotenv.

ObiettivoSchema di codice
Ordinamento ascendente.sort("field", pymongo.ASCENDING)
Ordinamento discendente.sort("field", pymongo.DESCENDING)
Ordinamento su più campi.sort([("f1", pymongo.ASCENDING), ("f2", pymongo.DESCENDING)])
Primi N risultati.sort(...).limit(N)
Ordinamento veloce su grandi datiCrea un indice sul campo di ordinamento

Capitoli correlati in questa serie:

Was this page helpful?