W3docs

MongoDB Find

Aprenda a recuperar documentos do MongoDB com Python usando find_one(), find(), projeções, operadores de consulta, sort, skip e limit com PyMongo.

Este capítulo explica como recuperar documentos de uma coleção MongoDB usando o driver pymongo do Python. Você aprenderá os métodos find_one() e find(), como filtrar resultados com operadores de consulta, como controlar quais campos são retornados com projeções, e como ordenar, pular e limitar resultados.

Configuração

Certifique-se de que o pymongo está instalado antes de executar qualquer exemplo:

pip install pymongo

Todos os exemplos abaixo pressupõem um servidor MongoDB ativo em mongodb://localhost:27017/. Para acompanhar na sua própria máquina, inicie o MongoDB com mongod ou use um cluster gratuito na nuvem (MongoDB Atlas).

Preparando Dados de Exemplo

Os exemplos neste capítulo usam uma coleção customers contendo estes cinco documentos. Execute este código uma vez para preenchê-la:

import pymongo

client = pymongo.MongoClient("mongodb://localhost:27017/")
db = client["mydatabase"]
col = db["customers"]

# Insert sample documents (skip if already inserted)
col.drop()  # start fresh
col.insert_many([
    {"name": "Alice",   "age": 28, "city": "London"},
    {"name": "Bob",     "age": 34, "city": "Paris"},
    {"name": "Carol",   "age": 22, "city": "London"},
    {"name": "David",   "age": 40, "city": "Berlin"},
    {"name": "Eve",     "age": 34, "city": "Paris"},
])
print("Sample data ready.")

Saída esperada:

Sample data ready.

O PyMongo adiciona automaticamente um campo _id único (um bson.ObjectId) a todo documento que ainda não possui um.

Recuperando um Único Documento com find_one()

find_one() retorna o primeiro documento que corresponde ao filtro, ou None se nenhum documento corresponder. É a escolha certa quando você espera exatamente um resultado (por exemplo, ao buscar um usuário por e-mail).

# Retrieve the first document in the collection
doc = col.find_one()
print(doc)
# {'_id': ObjectId('...'), 'name': 'Alice', 'age': 28, 'city': 'London'}

Passe um filtro para corresponder a um documento específico:

# Find the customer named Bob
bob = col.find_one({"name": "Bob"})
print(bob)
# {'_id': ObjectId('...'), 'name': 'Bob', 'age': 34, 'city': 'Paris'}

Se nenhum documento corresponder, find_one() retorna None, portanto sempre se proteja contra isso:

result = col.find_one({"name": "Zara"})
if result is None:
    print("No document found.")

Recuperando Múltiplos Documentos com find()

find() retorna um cursor — um iterador lazy sobre todos os documentos correspondentes. Nada é buscado no servidor até que você itere.

Recuperar Todos os Documentos

# Iterate every document in the collection
for doc in col.find():
    print(doc["name"], doc["age"])

Saída esperada (a ordem pode variar sem uma ordenação explícita):

Alice 28
Bob 34
Carol 22
David 40
Eve 34

Filtrar com Correspondência Exata

Passe um dicionário como primeiro argumento para find():

# All customers in London
for doc in col.find({"city": "London"}):
    print(doc["name"])
# Alice
# Carol

Projeções — Escolhendo Quais Campos Retornar

Por padrão, o MongoDB retorna todos os campos, incluindo _id. Uma projeção permite incluir ou excluir campos específicos, o que reduz o tráfego de rede e o uso de memória.

Passe a projeção como segundo argumento posicional (ou argumento nomeado projection):

# Return only name and city; suppress _id
for doc in col.find({}, {"_id": 0, "name": 1, "city": 1}):
    print(doc)
# {'name': 'Alice', 'city': 'London'}
# {'name': 'Bob',   'city': 'Paris'}
# ...

Regras para projeções:

  • Use 1 para incluir um campo, 0 para excluí-lo.
  • Você não pode misturar inclusão e exclusão na mesma projeção, exceto para _id (que sempre pode ser explicitamente definido como 0).

Operadores de Consulta

O MongoDB fornece um rico conjunto de operadores para filtrar documentos. Passe-os dentro do dicionário de filtro.

Operadores de Comparação

OperadorSignificadoExemplo
$eqIgual (padrão){"age": {"$eq": 34}}
$neDiferente{"city": {"$ne": "Paris"}}
$gtMaior que{"age": {"$gt": 30}}
$gteMaior ou igual a{"age": {"$gte": 34}}
$ltMenor que{"age": {"$lt": 30}}
$lteMenor ou igual a{"age": {"$lte": 28}}
$inValor na lista{"city": {"$in": ["London", "Berlin"]}}
$ninValor não está na lista{"city": {"$nin": ["Paris"]}}

Exemplo — clientes com mais de 30 anos:

for doc in col.find({"age": {"$gt": 30}}, {"_id": 0, "name": 1, "age": 1}):
    print(doc)
# {'name': 'Bob',   'age': 34}
# {'name': 'David', 'age': 40}
# {'name': 'Eve',   'age': 34}

Exemplo — clientes em London ou Berlin:

for doc in col.find(
    {"city": {"$in": ["London", "Berlin"]}},
    {"_id": 0, "name": 1, "city": 1}
):
    print(doc)
# {'name': 'Alice', 'city': 'London'}
# {'name': 'Carol', 'city': 'London'}
# {'name': 'David', 'city': 'Berlin'}

Operadores Lógicos

AND implícito — fornecer múltiplas chaves em um único dicionário de filtro significa que todas as condições devem ser satisfeitas:

# Age > 30 AND city is Paris
for doc in col.find({"age": {"$gt": 30}, "city": "Paris"}, {"_id": 0}):
    print(doc)
# {'name': 'Bob', 'age': 34, 'city': 'Paris'}
# {'name': 'Eve', 'age': 34, 'city': 'Paris'}

$and é necessário quando você precisa aplicar duas condições diferentes ao mesmo campo:

# Age between 28 (inclusive) and 40 (exclusive)
query = {"$and": [{"age": {"$gte": 28}}, {"age": {"$lt": 40}}]}
for doc in col.find(query, {"_id": 0, "name": 1, "age": 1}):
    print(doc)
# {'name': 'Alice', 'age': 28}
# {'name': 'Bob',   'age': 34}
# {'name': 'Eve',   'age': 34}

$or — pelo menos uma condição deve ser satisfeita:

# City is Berlin OR age is 22
for doc in col.find(
    {"$or": [{"city": "Berlin"}, {"age": 22}]},
    {"_id": 0, "name": 1}
):
    print(doc)
# {'name': 'Carol'}
# {'name': 'David'}

Correspondência de Padrões com $regex

Use $regex para comparar campos string com uma expressão regular:

# Names that start with the letter 'C' or 'E' (case-sensitive)
for doc in col.find({"name": {"$regex": "^[CE]"}}, {"_id": 0, "name": 1}):
    print(doc)
# {'name': 'Carol'}
# {'name': 'Eve'}

Para correspondência sem diferenciação de maiúsculas/minúsculas, adicione $options: "i":

for doc in col.find(
    {"city": {"$regex": "london", "$options": "i"}},
    {"_id": 0, "name": 1, "city": 1}
):
    print(doc)
# {'name': 'Alice', 'city': 'London'}
# {'name': 'Carol', 'city': 'London'}

Ordenando Resultados

Encadeie .sort() no cursor. Passe o nome do campo e uma constante de direção:

  • pymongo.ASCENDING (ou 1) — A → Z, do menor para o maior
  • pymongo.DESCENDING (ou -1) — Z → A, do maior para o menor
# Sort by age ascending
for doc in col.find({}, {"_id": 0, "name": 1, "age": 1}).sort("age", pymongo.ASCENDING):
    print(doc)
# {'name': 'Carol', 'age': 22}
# {'name': 'Alice', 'age': 28}
# {'name': 'Bob',   'age': 34}
# {'name': 'Eve',   'age': 34}
# {'name': 'David', 'age': 40}

Ordene por múltiplos campos passando uma lista de tuplas (campo, direção):

# Sort by age descending, then by name ascending (tiebreak)
order = [("age", pymongo.DESCENDING), ("name", pymongo.ASCENDING)]
for doc in col.find({}, {"_id": 0, "name": 1, "age": 1}).sort(order):
    print(doc)
# {'name': 'David', 'age': 40}
# {'name': 'Bob',   'age': 34}
# {'name': 'Eve',   'age': 34}
# {'name': 'Alice', 'age': 28}
# {'name': 'Carol', 'age': 22}

Limitando Resultados

.limit(n) limita o número de documentos retornados. Isso é útil para exibir os N melhores resultados.

# Top 3 youngest customers
for doc in col.find({}, {"_id": 0, "name": 1, "age": 1}).sort("age", 1).limit(3):
    print(doc)
# {'name': 'Carol', 'age': 22}
# {'name': 'Alice', 'age': 28}
# {'name': 'Bob',   'age': 34}

Pulando Documentos (Paginação)

.skip(n) pula os primeiros n documentos. Combinado com .limit(), habilita a paginação baseada em páginas:

PAGE_SIZE = 2

def get_page(page_number):
    """Return one page of customers sorted by age (page_number is 0-indexed)."""
    return list(
        col.find({}, {"_id": 0, "name": 1, "age": 1})
           .sort("age", pymongo.ASCENDING)
           .skip(page_number * PAGE_SIZE)
           .limit(PAGE_SIZE)
    )

print(get_page(0))  # [{'name': 'Carol', 'age': 22}, {'name': 'Alice', 'age': 28}]
print(get_page(1))  # [{'name': 'Bob', 'age': 34},   {'name': 'Eve', 'age': 34}]
print(get_page(2))  # [{'name': 'David', 'age': 40}]

Para coleções grandes, prefira a paginação baseada em cursor (filtrando pelo último _id visto) em vez de skip(), porque skip() precisa percorrer e descartar documentos, o que fica lento à medida que o deslocamento cresce.

Contando Documentos Correspondentes

Use count_documents() com um filtro para contar correspondências sem buscar os documentos:

london_count = col.count_documents({"city": "London"})
print(london_count)  # 2

total = col.count_documents({})
print(total)  # 5

Evite o método .count() mais antigo em cursores — foi descontinuado no PyMongo 3.7 e removido no PyMongo 4.

Verificando se um Documento Existe

Quando você só precisa saber se pelo menos um documento corresponde, use find_one() (mais barato do que contar):

exists = col.find_one({"city": "Berlin"}) is not None
print(exists)  # True

Armadilhas Comuns

O cursor se esgota após uma iteração. Se você iterar o mesmo cursor duas vezes, o segundo loop não produz nada. Chame find() novamente ou converta para uma lista:

cursor = col.find({"city": "Paris"})
results = list(cursor)   # materialise once
print(len(results))      # 2
# Now you can iterate `results` as many times as you like

find_one() vs find() — escolha o correto. Se você sabe que existe no máximo uma correspondência (por exemplo, consultando por um campo único como e-mail), use find_one(). Usar find() obriga você a iterar mesmo quando só precisa de um resultado.

Filtro None vs dicionário vazio. Tanto find() quanto find({}) retornam todos os documentos. Evite passar None explicitamente — use {} para maior clareza.

Capítulos Relacionados

  • MongoDB Insert — inserir documentos em uma coleção antes de consultá-los
  • MongoDB Query — cobertura mais aprofundada de expressões de consulta e padrões de filtragem
  • MongoDB Sort — cobertura dedicada à ordenação por múltiplos campos
  • MongoDB Limit — limit e sua interação com índices
  • MongoDB Update — modificar documentos que você encontrou
  • MongoDB Delete — remover documentos correspondentes
Was this page helpful?