Ordenação no MongoDB
Aprenda a ordenar resultados de consultas do MongoDB em Python usando o método sort() do PyMongo — ascendente, descendente, múltiplos campos, com limit e filtro.
Este capítulo explica como ordenar os resultados de consultas do MongoDB em Python usando o driver pymongo. Você aprenderá a ordenar por um único campo em ordem ascendente ou descendente, ordenar por múltiplos campos ao mesmo tempo, combinar ordenação com filtragem e limitação, e entender quando um índice torna a ordenação mais rápida.
Pré-requisitos
Você deve estar familiarizado com a conexão ao MongoDB e a consulta de documentos. Se ainda não fez isso, leia primeiro MongoDB Find e MongoDB Query.
Os exemplos abaixo assumem uma coleção chamada products em um banco de dados chamado store. Você pode inserir os documentos de exemplo usados nesta página com:
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.")O Método sort()
O método sort() é chamado sobre um cursor (o objeto retornado por find()) e informa ao MongoDB em que ordem retornar os documentos. Sua assinatura é:
cursor.sort(key_or_list, direction=None)key_or_list— um nome de campo (string) ao ordenar por um único campo, ou uma lista de tuplas(field, direction)ao ordenar por múltiplos campos.direction—pymongo.ASCENDING(valor1) oupymongo.DESCENDING(valor-1). Obrigatório quandokey_or_listé uma string simples; omita ao usar a forma de lista.
Usar as constantes nomeadas (pymongo.ASCENDING / pymongo.DESCENDING) em vez de inteiros brutos torna o código mais fácil de ler e evita erros de interpretação.
Ordenando em Ordem Ascendente
Passe pymongo.ASCENDING como segundo argumento para ordenar do menor para o maior valor:
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)Saída esperada (mais baratos primeiro):
{'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}A projeção {"_id": 0, "name": 1, "price": 1} limita os campos retornados a name e price, mantendo a saída concisa. Projeções são abordadas em MongoDB Find.
Ordenando em Ordem Descendente
Passe pymongo.DESCENDING para inverter a ordem (do maior para o menor):
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)Saída esperada (mais caros primeiro):
{'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}Ordenando por Múltiplos Campos
Quando você deseja ordenar por mais de um campo — por exemplo, por categoria primeiro e depois por preço dentro de cada categoria — passe uma lista de tuplas (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)Saída esperada (categorias de A-Z, mais baratos primeiro dentro de cada 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}Os campos de ordenação são aplicados da esquerda para a direita: o MongoDB primeiro ordena todos os documentos por category, depois desempata dentro do mesmo valor de categoria usando price.
Combinando sort() com Filtragem
sort() funciona com qualquer filtro de consulta. O filtro seleciona quais documentos correspondem; sort() então ordena apenas os documentos correspondentes:
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)Saída esperada:
{'name': 'Mouse', 'price': 29.99}
{'name': 'Keyboard', 'price': 49.99}
{'name': 'Monitor', 'price': 319.99}Veja MongoDB Query para mais opções de filtragem, como consultas de intervalo ($gt, $lt) e correspondência de padrões.
Combinando sort() com limit()
Encadeie limit() após sort() para obter os N primeiros (ou últimos) documentos. A ordem do encadeamento não importa — o MongoDB sempre aplica a ordenação antes do 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)Saída esperada:
{'name': 'Monitor', 'price': 319.99}
{'name': 'Desk', 'price': 249.99}
{'name': 'Chair', 'price': 189.99}Leia MongoDB Limit para mais informações sobre como controlar o número de documentos retornados.
Desempenho: Use um Índice para Coleções Grandes
Para coleções pequenas, o MongoDB ordena os resultados em memória. Em uma coleção grande, uma ordenação em memória pode ser lenta e — se ultrapassar 100 MB — o MongoDB retornará um erro. Criar um índice no campo de ordenação permite que o MongoDB retorne dados pré-ordenados sem varrer toda a coleção:
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)Para ordenações por múltiplos campos, crie um índice composto cujos campos e direções correspondam à sua ordenação:
col.create_index([
("category", pymongo.ASCENDING),
("price", pymongo.ASCENDING),
])Você só precisa criar cada índice uma vez. Chamadas repetidas a create_index() com a mesma chave são seguras — o PyMongo verifica se o índice já existe.
Armazenando a String de Conexão com Segurança
Os exemplos acima codificam diretamente a string de conexão por simplicidade. Em uma aplicação real, armazene-a em uma variável de ambiente:
import os
import pymongo
client = pymongo.MongoClient(os.environ["MONGODB_URI"])Defina a variável no seu shell (export MONGODB_URI="mongodb://localhost:27017/") ou use um arquivo .env com uma biblioteca como python-dotenv.
Resumo
| Objetivo | Padrão de código |
|---|---|
| Ordenar ascendente | .sort("field", pymongo.ASCENDING) |
| Ordenar descendente | .sort("field", pymongo.DESCENDING) |
| Ordenar por múltiplos campos | .sort([("f1", pymongo.ASCENDING), ("f2", pymongo.DESCENDING)]) |
| Top N resultados | .sort(...).limit(N) |
| Ordenação rápida em grandes volumes | Crie um índice no campo de ordenação |
Capítulos relacionados desta série:
- MongoDB Find — recuperando documentos com
find()efind_one() - MongoDB Query — filtragem com operadores de consulta
- MongoDB Limit — controlando quantos documentos são retornados
- MongoDB Update — modificando documentos em uma coleção