Programador Leigo
MongoDB 11 min leitura 15 MAR 2026

MongoDB com Python e PyMongo: guia prático

Conecte Python ao MongoDB e domine operações CRUD com PyMongo. Do insert ao aggregate.


O que é o MongoDB?

O MongoDB é um banco de dados NoSQL orientado a documentos. Em vez de tabelas com linhas e colunas, ele armazena dados como documentos JSON (internamente BSON). Cada documento pode ter uma estrutura diferente, o que dá flexibilidade enorme para modelar dados.

Conceito SQL Equivalente MongoDB
Tabela Coleção (collection)
Linha Documento (document)
Coluna Campo (field)
JOIN Embedding / Lookup

Um documento se parece com um dicionário Python:

{
    "_id": "664f1a2b3c4d5e6f7a8b9c0d",
    "titulo": "Aprender MongoDB",
    "autor": "Ana Silva",
    "tags": ["python", "nosql"],
    "publicado": True,
    "visualizacoes": 1250
}

O campo tags é uma lista dentro do documento. Você pode aninhar listas, subdocumentos e qualquer estrutura que um JSON suporta.

Instalação e conexão

Instale o PyMongo (driver oficial) com pip:

pip install pymongo

Para rodar o MongoDB, use Docker, instale localmente ou crie um cluster gratuito no MongoDB Atlas.

Conexão local

from pymongo import MongoClient

client = MongoClient("mongodb://localhost:27017/")
db = client["meu_blog"]
posts = db["posts"]

Conexão ao Atlas

pip install "pymongo[srv]"
uri = "mongodb+srv://usuario:senha@cluster0.xxxxx.mongodb.net/"
client = MongoClient(uri)
db = client["meu_blog"]

Se a coleção não existir, o MongoDB a cria automaticamente ao inserir o primeiro documento.

Create: inserindo documentos

posts = db["posts"]

# Inserir um documento
resultado = posts.insert_one({
    "titulo": "Introducao ao MongoDB",
    "autor": "Carlos Lima",
    "tags": ["mongodb", "nosql"],
    "publicado": True,
    "visualizacoes": 0
})
print(f"ID gerado: {resultado.inserted_id}")

# Inserir varios documentos
varios = [
    {"titulo": "Python para iniciantes", "autor": "Ana Silva",
     "tags": ["python"], "publicado": True, "visualizacoes": 3200},
    {"titulo": "Flask vs Django", "autor": "Carlos Lima",
     "tags": ["python", "web"], "publicado": True, "visualizacoes": 1850},
    {"titulo": "Redis na pratica", "autor": "Julia Santos",
     "tags": ["redis", "cache"], "publicado": False, "visualizacoes": 0},
]
resultado = posts.insert_many(varios)
print(f"{len(resultado.inserted_ids)} posts inseridos")

Read: buscando documentos

# Buscar um documento
post = posts.find_one({"titulo": "Introducao ao MongoDB"})

# Buscar pelo _id
from bson.objectid import ObjectId
post = posts.find_one({"_id": ObjectId("664f1a2b3c4d5e6f7a8b9c0d")})

# Buscar varios (retorna um cursor iteravel)
publicados = posts.find({"publicado": True})
for post in publicados:
    print(f"{post['titulo']} - {post['visualizacoes']} views")

Filtros com operadores

# Visualizacoes maiores que 1000
posts.find({"visualizacoes": {"$gt": 1000}})

# Entre 500 e 2000
posts.find({"visualizacoes": {"$gte": 500, "$lte": 2000}})

# Autor e Ana OU Julia
posts.find({"autor": {"$in": ["Ana Silva", "Julia Santos"]}})

# Posts com a tag "python"
posts.find({"tags": "python"})
Operador Significado Exemplo
$gt Maior que {"idade": {"$gt": 18}}
$gte Maior ou igual {"nota": {"$gte": 7.0}}
$lt Menor que {"preco": {"$lt": 100}}
$lte Menor ou igual {"estoque": {"$lte": 5}}
$ne Diferente de {"status": {"$ne": "inativo"}}
$in Está na lista {"cor": {"$in": ["azul"]}}
$exists Campo existe {"email": {"$exists": True}}
$regex Expressão regular {"nome": {"$regex": "^Ana"}}

Projeções e ordenação

# Retornar apenas titulo e autor
posts.find({"publicado": True}, {"titulo": 1, "autor": 1, "_id": 0})

# Ordenar por visualizacoes (decrescente) e limitar
from pymongo import DESCENDING
top_3 = posts.find().sort("visualizacoes", DESCENDING).limit(3)

# Contar documentos
total = posts.count_documents({"publicado": True})

Update: atualizando documentos

# Atualizar um campo com $set
posts.update_one(
    {"titulo": "Introducao ao MongoDB"},
    {"$set": {"visualizacoes": 150}}
)

# Incrementar um valor com $inc
posts.update_one(
    {"titulo": "Introducao ao MongoDB"},
    {"$inc": {"visualizacoes": 1}}
)

# Adicionar a uma lista com $push
posts.update_one(
    {"titulo": "Introducao ao MongoDB"},
    {"$push": {"tags": "banco-de-dados"}}
)

# Atualizar varios documentos
resultado = posts.update_many(
    {"autor": "Julia Santos"},
    {"$set": {"publicado": True}}
)
print(f"{resultado.modified_count} post(s) atualizado(s)")

Delete: removendo documentos

posts.delete_one({"titulo": "Redis na pratica"})

resultado = posts.delete_many({"publicado": False})
print(f"{resultado.deleted_count} rascunho(s) removido(s)")

Aggregation Pipeline

O aggregation pipeline é o recurso mais poderoso do MongoDB para análise de dados. Cada estágio recebe documentos, processa e passa para o próximo.

# Contar posts por autor
pipeline = [
    {"$group": {
        "_id": "$autor",
        "total_posts": {"$sum": 1},
        "media_views": {"$avg": "$visualizacoes"}
    }},
    {"$sort": {"total_posts": -1}}
]

for r in posts.aggregate(pipeline):
    print(f"{r['_id']}: {r['total_posts']} posts, media {r['media_views']:.0f} views")

# Top tags mais usadas
pipeline = [
    {"$unwind": "$tags"},
    {"$group": {"_id": "$tags", "contagem": {"$sum": 1}}},
    {"$sort": {"contagem": -1}},
    {"$limit": 5}
]

for tag in posts.aggregate(pipeline):
    print(f"#{tag['_id']}: {tag['contagem']} usos")
Estágio Função
$match Filtrar documentos (como WHERE no SQL)
$group Agrupar e calcular (como GROUP BY)
$sort Ordenar resultados
$limit Limitar quantidade de resultados
$project Escolher e renomear campos
$unwind Desmembrar arrays em documentos individuais
$lookup JOIN com outra coleção

Índices

Índices aceleram consultas. Sem eles, o MongoDB percorre todos os documentos da coleção.

posts.create_index("titulo")                          # indice simples
posts.create_index("titulo", unique=True)             # indice unico
posts.create_index([("autor", 1), ("visualizacoes", -1)])  # composto

# Indice de texto para busca textual
posts.create_index([("titulo", "text"), ("conteudo", "text")])
resultados = posts.find({"$text": {"$search": "MongoDB Python"}})

Crie índices nos campos usados com frequência em filtros e ordenações. Evite criar índices em todos os campos — eles ocupam espaço e tornam escritas mais lentas.

Exemplo prático: catálogo de produtos

from pymongo import MongoClient, DESCENDING

client = MongoClient("mongodb://localhost:27017/")
db = client["loja"]
produtos = db["produtos"]

# Inserir catalogo
produtos.delete_many({})
produtos.insert_many([
    {"nome": "Notebook Pro", "categoria": "eletronicos",
     "preco": 4599.90, "estoque": 23, "avaliacao": 4.5},
    {"nome": "Mouse Gamer", "categoria": "perifericos",
     "preco": 189.90, "estoque": 150, "avaliacao": 4.2},
    {"nome": "Monitor 4K", "categoria": "perifericos",
     "preco": 2199.90, "estoque": 35, "avaliacao": 4.7},
    {"nome": "Teclado Mecanico", "categoria": "perifericos",
     "preco": 349.90, "estoque": 80, "avaliacao": 4.3},
    {"nome": "SSD 1TB NVMe", "categoria": "armazenamento",
     "preco": 459.90, "estoque": 200, "avaliacao": 4.8},
])

# Buscar por faixa de preco
for p in produtos.find({"preco": {"$gte": 100, "$lte": 500}}).sort("preco", DESCENDING):
    print(f"  {p['nome']}: R${p['preco']:.2f}")

# Estatisticas por categoria
pipeline = [
    {"$group": {
        "_id": "$categoria",
        "total": {"$sum": 1},
        "preco_medio": {"$avg": "$preco"},
        "estoque_total": {"$sum": "$estoque"}
    }},
    {"$sort": {"preco_medio": -1}}
]

print("\nEstatisticas por categoria:")
for r in produtos.aggregate(pipeline):
    print(f"  {r['_id']}: {r['total']} produtos, media R${r['preco_medio']:.2f}")

Próximos passos

Com PyMongo você tem acesso completo ao MongoDB a partir do Python. Para evoluir, explore o Motor (driver assíncrono para asyncio), aprenda a modelar dados com embedding vs referencing e estude padrões de índices para otimizar consultas. Se estiver usando Flask ou FastAPI, combine o MongoDB com essas frameworks para criar APIs completas.

Continue lendo

Compartilhar