O MongoDB é um banco de dados NoSQL orientado a documentos que armazena dados como documentos flexíveis no formato JSON, em vez de linhas e colunas. Enquanto bancos de dados relacionais exigem que você defina um esquema previamente e reestruture tabelas conforme os requisitos mudam, o MongoDB permite que cada documento em uma coleção tenha campos diferentes — tornando-o ideal para aplicações onde as estruturas de dados evoluem rapidamente. Este guia aborda a instalação do MongoDB, operações CRUD essenciais, estratégias de indexação e configuração de replica set para ambientes de produção.

Pré-requisitos

  • Um servidor Linux (Ubuntu 22.04 ou RHEL 8+ recomendado) com pelo menos 2 GB de RAM
  • Acesso root ou sudo para a instalação
  • Conhecimento básico do formato de dados JSON
  • Familiaridade com ferramentas de linha de comando

Instalando o MongoDB

Ubuntu/Debian

# Importar a chave GPG do MongoDB
curl -fsSL https://www.mongodb.org/static/pgp/server-7.0.asc | \
  sudo gpg -o /usr/share/keyrings/mongodb-server-7.0.gpg --dearmor

# Adicionar o repositório
echo "deb [ arch=amd64,arm64 signed-by=/usr/share/keyrings/mongodb-server-7.0.gpg ] \
  https://repo.mongodb.org/apt/ubuntu jammy/mongodb-org/7.0 multiverse" | \
  sudo tee /etc/apt/sources.list.d/mongodb-org-7.0.list

# Instalar o MongoDB
sudo apt update
sudo apt install -y mongodb-org

# Iniciar e habilitar o serviço
sudo systemctl start mongod
sudo systemctl enable mongod

# Verificar se está em execução
sudo systemctl status mongod
mongosh --eval "db.version()"

RHEL/CentOS

# Criar o arquivo do repositório
cat <<'EOF' | sudo tee /etc/yum.repos.d/mongodb-org-7.0.repo
[mongodb-org-7.0]
name=MongoDB Repository
baseurl=https://repo.mongodb.org/yum/redhat/$releasever/mongodb-org/7.0/x86_64/
gpgcheck=1
enabled=1
gpgkey=https://www.mongodb.org/static/pgp/server-7.0.asc
EOF

sudo dnf install -y mongodb-org
sudo systemctl start mongod
sudo systemctl enable mongod

Docker

docker run -d \
  --name mongodb \
  -p 27017:27017 \
  -v mongodb-data:/data/db \
  -e MONGO_INITDB_ROOT_USERNAME=admin \
  -e MONGO_INITDB_ROOT_PASSWORD=secretpassword \
  mongo:7

Operações CRUD Essenciais

Conecte ao MongoDB usando o shell:

# Conectar ao MongoDB local
mongosh

# Conectar a um servidor remoto com autenticação
mongosh "mongodb://admin:password@192.168.1.100:27017/admin"

Create — Inserindo Documentos

// Alternar para (ou criar) um banco de dados
use myapp

// Inserir um único documento
db.users.insertOne({
  name: "Alice Johnson",
  email: "alice@example.com",
  role: "admin",
  skills: ["python", "docker", "kubernetes"],
  created: new Date()
})

// Inserir múltiplos documentos
db.users.insertMany([
  { name: "Bob Smith", email: "bob@example.com", role: "developer", skills: ["javascript", "react"] },
  { name: "Carol Lee", email: "carol@example.com", role: "devops", skills: ["terraform", "aws", "docker"] }
])

O MongoDB cria o banco de dados e a coleção automaticamente na primeira inserção — sem necessidade de CREATE TABLE ou CREATE DATABASE.

Read — Consultando Documentos

// Encontrar todos os documentos em uma coleção
db.users.find()

// Encontrar com um filtro
db.users.find({ role: "admin" })

// Consultar campos aninhados e arrays
db.users.find({ skills: "docker" })           // Array contém "docker"
db.users.find({ "skills.0": "python" })        // Primeira skill é "python"

// Operadores de comparação
db.users.find({ age: { $gt: 25 } })            // Maior que
db.users.find({ role: { $in: ["admin", "devops"] } })  // Está no array

// Projeção — selecionar campos específicos
db.users.find({ role: "admin" }, { name: 1, email: 1, _id: 0 })

// Ordenar e limitar
db.users.find().sort({ created: -1 }).limit(10)

// Contar documentos
db.users.countDocuments({ role: "developer" })

Update — Modificando Documentos

// Atualizar um documento
db.users.updateOne(
  { email: "alice@example.com" },
  { $set: { role: "superadmin", lastLogin: new Date() } }
)

// Adicionar a um array
db.users.updateOne(
  { email: "bob@example.com" },
  { $push: { skills: "typescript" } }
)

// Atualizar múltiplos documentos
db.users.updateMany(
  { role: "developer" },
  { $set: { department: "engineering" } }
)

// Upsert — atualiza se existir, insere se não existir
db.users.updateOne(
  { email: "dave@example.com" },
  { $set: { name: "Dave Wilson", role: "intern" } },
  { upsert: true }
)

Delete — Removendo Documentos

// Deletar um documento
db.users.deleteOne({ email: "dave@example.com" })

// Deletar múltiplos documentos
db.users.deleteMany({ role: "intern" })

// Remover uma coleção inteira
db.users.drop()

Indexação para Desempenho

Sem índices, o MongoDB realiza uma varredura completa da coleção — lendo cada documento para encontrar correspondências. Em uma coleção com milhões de documentos, isso leva segundos em vez de milissegundos.

// Criar um índice de campo único
db.users.createIndex({ email: 1 })           // Ascendente

// Criar um índice composto (múltiplos campos)
db.users.createIndex({ role: 1, created: -1 })

// Criar um índice único (garante unicidade)
db.users.createIndex({ email: 1 }, { unique: true })

// Criar um índice de texto para busca full-text
db.articles.createIndex({ title: "text", body: "text" })
db.articles.find({ $text: { $search: "mongodb tutorial" } })

// Listar todos os índices de uma coleção
db.users.getIndexes()

// Explicar uma consulta para ver se utiliza índice
db.users.find({ email: "alice@example.com" }).explain("executionStats")

Boas práticas de indexação:

  • Indexe campos usados em filtros find(), sort() e $match em agregações
  • Em índices compostos, ordene os campos do mais seletivo para o menos seletivo
  • Evite indexar campos com baixa cardinalidade (por exemplo, campos booleanos com apenas true/false)
  • Cada índice consome RAM — monitore com db.stats() e db.collection.stats()

Comparando MongoDB com Outros Bancos de Dados

RecursoMongoDBPostgreSQLMySQLRedis
Modelo de dadosDocumentos (JSON)Relacional (tabelas)Relacional (tabelas)Chave-valor / estruturas de dados
EsquemaFlexível (sem esquema)Rígido (SQL DDL)Rígido (SQL DDL)Sem esquema
Linguagem de consultaMQL + AgregaçãoSQLSQLComandos
Joins$lookup (limitado)Joins SQL completosJoins SQL completosNenhum
TransaçõesACID multidocumentoACID completoACID completoAtômico por operação
EscalonamentoHorizontal (sharding)Vertical (+ read replicas)Vertical (+ read replicas)Em memória, horizontal
Ideal paraEsquemas flexíveis, desenvolvimento ágilConsultas complexas, integridade dos dadosAplicações web, WordPressCache, sessões, tempo real

Pipeline de Agregação

O pipeline de agregação é a resposta do MongoDB às consultas SQL complexas com GROUP BY, JOIN e subconsultas:

// Contar usuários por função
db.users.aggregate([
  { $group: { _id: "$role", count: { $sum: 1 } } },
  { $sort: { count: -1 } }
])

// Encontrar as skills mais comuns entre todos os usuários
db.users.aggregate([
  { $unwind: "$skills" },
  { $group: { _id: "$skills", count: { $sum: 1 } } },
  { $sort: { count: -1 } },
  { $limit: 10 }
])

// Unir usuários com seus pedidos (como JOIN no SQL)
db.orders.aggregate([
  { $lookup: {
      from: "users",
      localField: "userId",
      foreignField: "_id",
      as: "user"
  }},
  { $unwind: "$user" },
  { $project: { orderTotal: 1, "user.name": 1, "user.email": 1 } }
])

Backup e Restauração

# Backup de um banco de dados específico
mongodump --db myapp --out /backup/$(date +%Y-%m-%d)

# Backup com autenticação
mongodump --uri="mongodb://admin:password@localhost:27017" --db myapp --out /backup/

# Backup de todos os bancos de dados
mongodump --out /backup/full-$(date +%Y-%m-%d)

# Restaurar um banco de dados
mongorestore --db myapp /backup/2025-12-13/myapp

# Restaurar descartando os dados existentes primeiro
mongorestore --drop --db myapp /backup/2025-12-13/myapp

Armadilhas e Casos Especiais

Limite de tamanho de documento: Um único documento MongoDB não pode exceder 16 MB. Para armazenar arquivos grandes, use GridFS — a especificação do MongoDB para armazenar arquivos maiores que 16 MB distribuídos em múltiplos documentos.

Sem joins por padrão: Embora $lookup ofereça funcionalidade básica de join, ele é mais lento que joins relacionais. Projete seu esquema de documentos para incorporar dados relacionados dentro de um único documento quando possível (desnormalização).

Write concern e perda de dados: Por padrão, o MongoDB confirma escritas após alcançarem o primário. Se o primário falhar antes da replicação, os dados são perdidos. Para dados críticos, use writeConcern: { w: "majority" } para aguardar a replicação.

ObjectId não é sequencial: O campo _id padrão do MongoDB usa ObjectId, que codifica um timestamp mas não é estritamente sequencial. Não use a ordenação por _id como substituto para um campo de timestamp created.

Armazenamento mapeado em memória: O motor WiredTiger do MongoDB utiliza a RAM disponível para cache. Um servidor MongoDB com 8 GB de RAM e um banco de dados de 100 GB armazena em cache apenas o conjunto de trabalho ativo. Monitore as taxas de acerto ao cache com db.serverStatus().wiredTiger.cache.

Solução de Problemas

MongoDB não inicia

# Verificar o log em busca de erros
sudo journalctl -u mongod --no-pager -n 50

# Causa comum: espaço em disco insuficiente ou permissões incorretas
ls -la /var/lib/mongodb/
sudo chown -R mongodb:mongodb /var/lib/mongodb

Consultas lentas

// Use explain para verificar se as consultas usam índices
db.users.find({ email: "alice@example.com" }).explain("executionStats")

// Procure "COLLSCAN" na saída — significa que nenhum índice é utilizado
// Crie um índice no campo consultado
db.users.createIndex({ email: 1 })

Conexão recusada por clientes remotos

# O MongoDB vincula ao localhost por padrão
# Edite /etc/mongod.conf para permitir conexões remotas
# net:
#   bindIp: 0.0.0.0    # Escutar em todas as interfaces

# IMPORTANTE: Habilite a autenticação primeiro!
sudo systemctl restart mongod

Resumo

  • O MongoDB armazena documentos no formato JSON em coleções sem exigir um esquema predefinido — cada documento pode ter campos diferentes, tornando-o ideal para estruturas de dados em evolução
  • As operações CRUD usam métodos intuitivos como insertOne, find, updateOne e deleteOne com filtros de consulta em JSON em vez de SQL
  • Índices são essenciais para o desempenho — crie índices nos campos usados em consultas e operações de ordenação, e use explain() para verificar o uso de índices
  • O pipeline de agregação trata de transformações de dados complexas, agrupamentos e joins que exigiriam GROUP BY e JOIN em SQL
  • Faça backup regularmente com mongodump e teste a restauração com mongorestore — um backup que você não testou não é um backup de verdade
  • Projete documentos para incorporar dados relacionados em vez de normalizar entre coleções — isso reduz a necessidade de joins $lookup que são mais custosos

Artigos Relacionados