Arkanus
Menu
FALE CONOSCO
MongoDB

MongoDB: Guia Completo do Banco de Dados NoSQL Mais Popular

Entenda como MongoDB revolucionou persistência de dados com seu modelo de documentos flexível, perfeito para aplicações modernas que exigem agilidade e escala.

Equipe Arkanus

Equipe Arkanus

27/10/2025

MongoDB: Guia Completo do Banco de Dados NoSQL Mais Popular

MongoDB: Guia Completo do Banco de Dados NoSQL Mais Popular

Em um mundo onde esquemas de dados mudam rapidamente e escala horizontal é essencial, MongoDB emergiu como o banco de dados NoSQL mais popular. Seu modelo de documentos flexível e capacidades de sharding tornaram-no a escolha de empresas como Meta, eBay, Adobe e Forbes.

MongoDB NoSQL Database

O que é MongoDB?

MongoDB é um banco de dados NoSQL orientado a documentos que armazena dados em formato JSON-like (BSON). Ao invés de tabelas e linhas, MongoDB usa coleções e documentos, oferecendo flexibilidade de schema e escalabilidade horizontal nativa.

SQL vs NoSQL (MongoDB)

SQL (PostgreSQL/MySQL):

-- Schema rígido
CREATE TABLE usuarios (
    id SERIAL PRIMARY KEY,
    nome VARCHAR(100) NOT NULL,
    email VARCHAR(255) UNIQUE NOT NULL,
    idade INT
);

-- JOINs para relacionamentos
SELECT u.nome, p.titulo
FROM usuarios u
JOIN posts p ON p.usuario_id = u.id;

NoSQL (MongoDB):

// Schema flexível - documento JSON
{
  _id: ObjectId("507f1f77bcf86cd799439011"),
  nome: "João Silva",
  email: "joao@example.com",
  idade: 28,
  endereco: {  // Documento aninhado
    rua: "Av Principal",
    cidade: "São Paulo"
  },
  tags: ["developer", "javascript"],  // Array
  posts: [  // Embedded documents
    { titulo: "Meu Post", conteudo: "..." }
  ]
}

Por que MongoDB?

1. Schema Flexível

Adicione campos sem migrations:

// Documento 1
{
  _id: 1,
  nome: "João",
  email: "joao@example.com"
}

// Documento 2 - estrutura diferente OK!
{
  _id: 2,
  nome: "Maria",
  email: "maria@example.com",
  telefone: "11999999999",  // Campo novo
  enderecos: [  // Array complexo
    { tipo: "casa", cidade: "SP" },
    { tipo: "trabalho", cidade: "RJ" }
  ]
}

Perfeito para:

  • MVPs com requisitos em evolução
  • Dados semi-estruturados
  • Integração com APIs externas
  • Aplicações ágeis

2. Escalabilidade Horizontal

Sharding nativo para crescimento ilimitado:

// Shardeado por user_id
sh.shardCollection("app.usuarios", { user_id: 1 });

// MongoDB distribui automaticamente entre shards
// Shard 1: user_id 1-1000000
// Shard 2: user_id 1000001-2000000
// Shard 3: user_id 2000001-3000000

Escale horizontalmente adicionando mais servidores.

3. Documentos Ricos

Estruturas aninhadas naturais:

// Blog post com tudo embedded
{
  _id: ObjectId("..."),
  titulo: "Guia MongoDB",
  slug: "guia-mongodb",
  autor: {
    nome: "João Silva",
    email: "joao@example.com",
    avatar: "https://..."
  },
  conteudo: "...",
  tags: ["mongodb", "nosql", "database"],
  comentarios: [
    {
      autor: "Maria",
      texto: "Ótimo artigo!",
      data: ISODate("2024-10-27T10:30:00Z"),
      likes: 5
    },
    {
      autor: "Pedro",
      texto: "Muito útil",
      data: ISODate("2024-10-27T11:00:00Z"),
      likes: 3
    }
  ],
  metadados: {
    views: 1523,
    shares: 45,
    status: "publicado"
  },
  createdAt: ISODate("2024-10-27T09:00:00Z"),
  updatedAt: ISODate("2024-10-27T12:00:00Z")
}

Um documento = uma entidade completa. Sem JOINs necessários.

4. Queries Poderosas

// Find com filtros complexos
db.usuarios.find({
  idade: { $gte: 25, $lte: 35 },
  "endereco.cidade": "São Paulo",
  tags: { $in: ["javascript", "nodejs"] },
  status: "ativo"
});

// Aggregation pipeline
db.vendas.aggregate([
  // Stage 1: Filtrar
  { $match: { data: { $gte: ISODate("2024-01-01") } } },
  
  // Stage 2: Agrupar
  { $group: {
    _id: "$produto_id",
    total: { $sum: "$valor" },
    quantidade: { $sum: 1 },
    media: { $avg: "$valor" }
  }},
  
  // Stage 3: Ordenar
  { $sort: { total: -1 } },
  
  // Stage 4: Limitar
  { $limit: 10 }
]);

// Text search
db.artigos.createIndex({ titulo: "text", conteudo: "text" });
db.artigos.find({ $text: { $search: "mongodb nosql" } });

// Geospatial queries
db.locais.find({
  localizacao: {
    $near: {
      $geometry: { type: "Point", coordinates: [-73.9667, 40.78] },
      $maxDistance: 5000  // metros
    }
  }
});

CRUD Operations

Create

// Insert um documento
const result = await db.collection('usuarios').insertOne({
  nome: "João Silva",
  email: "joao@example.com",
  idade: 28,
  createdAt: new Date()
});

console.log(result.insertedId);

// Insert múltiplos
await db.collection('usuarios').insertMany([
  { nome: "Maria", email: "maria@example.com" },
  { nome: "Pedro", email: "pedro@example.com" }
]);

Read

// Buscar um
const usuario = await db.collection('usuarios').findOne({ 
  email: "joao@example.com" 
});

// Buscar múltiplos com filtros
const usuarios = await db.collection('usuarios')
  .find({ idade: { $gte: 25 } })
  .sort({ nome: 1 })
  .limit(10)
  .toArray();

// Projeção (selecionar campos)
const emails = await db.collection('usuarios')
  .find({}, { projection: { email: 1, nome: 1, _id: 0 } })
  .toArray();

Update

// Update um documento
await db.collection('usuarios').updateOne(
  { _id: ObjectId("...") },
  { 
    $set: { idade: 29 },
    $push: { tags: "mongodb" },
    $inc: { login_count: 1 }
  }
);

// Update múltiplos
await db.collection('usuarios').updateMany(
  { status: "inativo" },
  { $set: { status: "arquivado" } }
);

// Upsert (insert se não existir)
await db.collection('usuarios').updateOne(
  { email: "novo@example.com" },
  { $set: { nome: "Novo Usuario" } },
  { upsert: true }
);

Delete

// Deletar um
await db.collection('usuarios').deleteOne({ 
  _id: ObjectId("...") 
});

// Deletar múltiplos
await db.collection('usuarios').deleteMany({ 
  status: "spam" 
});

Modelagem de Dados

Embedding vs Referencing

Embedding (dados relacionados no mesmo documento):

// ✅ Use quando:
// - Dados acessados juntos sempre
// - Relação one-to-few
// - Dados não mudam muito

{
  _id: 1,
  nome: "João",
  endereco: {  // Embedded
    rua: "Av Principal",
    cidade: "São Paulo",
    cep: "01000-000"
  }
}

Referencing (IDs apontando para outros documentos):

// ✅ Use quando:
// - Dados grandes ou acessados independentemente
// - Relação many-to-many
// - Dados mudam frequentemente

// Usuário
{
  _id: 1,
  nome: "João"
}

// Posts (referenciando usuário)
{
  _id: 101,
  titulo: "Meu Post",
  autor_id: 1  // Referência
}

Indexação

Índices são cruciais para performance:

// Índice simples
db.usuarios.createIndex({ email: 1 });

// Índice composto
db.posts.createIndex({ autor_id: 1, data: -1 });

// Índice único
db.usuarios.createIndex({ email: 1 }, { unique: true });

// Índice de texto completo
db.artigos.createIndex({ titulo: "text", conteudo: "text" });

// Índice geoespacial
db.locais.createIndex({ localizacao: "2dsphere" });

// Índice parcial (só alguns documentos)
db.usuarios.createIndex(
  { email: 1 },
  { partialFilterExpression: { status: "ativo" } }
);

// TTL Index (auto-delete após X segundos)
db.sessoes.createIndex(
  { createdAt: 1 },
  { expireAfterSeconds: 3600 }  // 1 hora
);

// Analisar uso de índices
db.usuarios.find({ email: "joao@example.com" }).explain("executionStats");

Aggregation Framework

Pipeline poderoso para transformações complexas:

// Dashboard de analytics
db.vendas.aggregate([
  // 1. Filtrar período
  {
    $match: {
      data: { 
        $gte: ISODate("2024-01-01"),
        $lt: ISODate("2024-12-31")
      }
    }
  },
  
  // 2. Lookup (JOIN) com produtos
  {
    $lookup: {
      from: "produtos",
      localField: "produto_id",
      foreignField: "_id",
      as: "produto"
    }
  },
  
  // 3. Unwind array
  { $unwind: "$produto" },
  
  // 4. Agrupar por categoria
  {
    $group: {
      _id: "$produto.categoria",
      totalVendas: { $sum: "$valor" },
      quantidade: { $sum: "$quantidade" },
      ticketMedio: { $avg: "$valor" },
      produtos: { $addToSet: "$produto.nome" }
    }
  },
  
  // 5. Adicionar campos calculados
  {
    $addFields: {
      lucroEstimado: { $multiply: ["$totalVendas", 0.3] }
    }
  },
  
  // 6. Ordenar
  { $sort: { totalVendas: -1 } },
  
  // 7. Formatar output
  {
    $project: {
      categoria: "$_id",
      totalVendas: { $round: ["$totalVendas", 2] },
      quantidade: 1,
      ticketMedio: { $round: ["$ticketMedio", 2] },
      totalProdutos: { $size: "$produtos" },
      _id: 0
    }
  }
]);

Transações ACID

MongoDB suporta transações multi-documento desde v4.0:

const session = client.startSession();

try {
  await session.withTransaction(async () => {
    // Operação 1: Debitar conta origem
    await db.collection('contas').updateOne(
      { _id: contaOrigem },
      { $inc: { saldo: -100 } },
      { session }
    );
    
    // Operação 2: Creditar conta destino
    await db.collection('contas').updateOne(
      { _id: contaDestino },
      { $inc: { saldo: 100 } },
      { session }
    );
    
    // Operação 3: Registrar transação
    await db.collection('transacoes').insertOne({
      origem: contaOrigem,
      destino: contaDestino,
      valor: 100,
      data: new Date()
    }, { session });
  });
  
  console.log("Transação commitada com sucesso");
} catch (error) {
  console.error("Transação abortada:", error);
} finally {
  await session.endSession();
}

Replicação e Alta Disponibilidade

Replica Sets:

┌────────────┐
│  Primary   │──┐ Writes
└────────────┘  │
      │         │
   Replicates   │
      │         │
      ├─────────┴─────┬─────────────┐
      │               │             │
┌────────────┐  ┌────────────┐  ┌────────────┐
│ Secondary  │  │ Secondary  │  │ Secondary  │
│ (Reads)    │  │ (Reads)    │  │ (Backup)   │
└────────────┘  └────────────┘  └────────────┘
  • Primary recebe writes
  • Secondaries replicam dados
  • Automatic failover se Primary cair
// Connection string com replica set
mongodb://mongo1:27017,mongo2:27017,mongo3:27017/mydb?replicaSet=rs0

// Read preference
const usuarios = await db.collection('usuarios')
  .find({})
  .readPreference('secondaryPreferred')  // Lê de secondary se disponível
  .toArray();

Change Streams

Reatividade em tempo real:

// Watch changes em coleção
const changeStream = db.collection('usuarios').watch();

changeStream.on('change', (change) => {
  console.log('Change detected:', change);
  
  if (change.operationType === 'insert') {
    console.log('Novo usuário:', change.fullDocument);
  }
  
  if (change.operationType === 'update') {
    console.log('Usuário atualizado:', change.documentKey);
  }
  
  if (change.operationType === 'delete') {
    console.log('Usuário deletado:', change.documentKey);
  }
});

// Watch pipeline específico
const pipeline = [
  { $match: { operationType: 'insert' } },
  { $match: { "fullDocument.status": "ativo" } }
];

const filteredStream = db.collection('usuarios').watch(pipeline);

ODMs e Integração

Mongoose (Node.js)

import mongoose from 'mongoose';

// Schema
const usuarioSchema = new mongoose.Schema({
  nome: { type: String, required: true },
  email: { type: String, required: true, unique: true },
  idade: { type: Number, min: 0, max: 150 },
  tags: [String],
  endereco: {
    rua: String,
    cidade: String,
    cep: String
  },
  posts: [{
    titulo: String,
    conteudo: String,
    data: { type: Date, default: Date.now }
  }]
}, {
  timestamps: true  // createdAt, updatedAt automáticos
});

// Métodos
usuarioSchema.methods.saudar = function() {
  return `Olá, ${this.nome}!`;
};

// Middleware
usuarioSchema.pre('save', async function(next) {
  // Hash password, etc
  next();
});

// Model
const Usuario = mongoose.model('Usuario', usuarioSchema);

// Usar
const usuario = new Usuario({
  nome: "João",
  email: "joao@example.com",
  idade: 28
});

await usuario.save();

const usuarios = await Usuario
  .find({ idade: { $gte: 25 } })
  .select('nome email')
  .sort('-createdAt')
  .limit(10);

Prisma (TypeScript)

datasource db {
  provider = "mongodb"
  url      = env("DATABASE_URL")
}

model Usuario {
  id        String   @id @default(auto()) @map("_id") @db.ObjectId
  email     String   @unique
  nome      String
  idade     Int?
  posts     Post[]
  createdAt DateTime @default(now())
  updatedAt DateTime @updatedAt
}

model Post {
  id        String   @id @default(auto()) @map("_id") @db.ObjectId
  titulo    String
  conteudo  String
  autor     Usuario  @relation(fields: [autorId], references: [id])
  autorId   String   @db.ObjectId
}
// Usar
const usuario = await prisma.usuario.create({
  data: {
    nome: "João",
    email: "joao@example.com",
    posts: {
      create: [
        { titulo: "Post 1", conteudo: "..." }
      ]
    }
  },
  include: { posts: true }
});

Performance Tips

// ✅ Use projeção para retornar só campos necessários
db.usuarios.find({}, { nome: 1, email: 1 });

// ✅ Use índices em campos filtrados/ordenados
db.posts.createIndex({ autor_id: 1, data: -1 });

// ✅ Limite resultados
db.posts.find().limit(20);

// ✅ Use lean() no Mongoose (objetos JS puros, mais rápido)
const usuarios = await Usuario.find().lean();

// ❌ Evite buscar documentos inteiros se não precisa
db.usuarios.find();  // Todos os campos

// ❌ Evite $where (lento)
db.usuarios.find({ $where: "this.idade > 25" });

// ✅ Use operadores normais
db.usuarios.find({ idade: { $gt: 25 } });

// ❌ Evite queries sem índice em coleções grandes
db.usuarios.find({ campo_sem_indice: valor });

MongoDB Atlas

Cloud managed MongoDB da própria MongoDB Inc:

  • Auto-scaling: Recursos ajustam automaticamente
  • Backups: Contínuos e point-in-time recovery
  • Monitoring: Dashboards e alertas
  • Global clusters: Multi-region com baixa latência
  • Free tier: M0 grátis para começar
  • Serverless: Pay-per-operation
// Connection string Atlas
mongodb+srv://usuario:senha@cluster0.mongodb.net/mydb?retryWrites=true&w=majority

Casos de Uso Ideais

Catálogos de Produtos: Schema flexível, busca rica ✅ Content Management: Documentos ricos, versionamento ✅ Real-time Analytics: Change streams, aggregations ✅ IoT / Sensor Data: Time-series, alta throughput ✅ User Profiles: Dados semi-estruturados ✅ Mobile Apps: Offline-first com MongoDB Realm

Transações Complexas: PostgreSQL melhor ❌ Joins Pesados: Relacional mais eficiente ❌ Dados Altamente Estruturados: SQL pode ser melhor

Conclusão

MongoDB revolucionou como pensamos sobre persistência de dados. Seu modelo de documentos flexível, escalabilidade horizontal nativa e rico ecossistema fazem dele uma escolha excelente para aplicações modernas que precisam:

Agilidade: Schema flexível acelera desenvolvimento ✅ Escala: Sharding nativo para crescimento horizontal ✅ Performance: Queries ricas e índices sofisticados ✅ Developer Experience: APIs naturais e ODMs poderosos

Na Arkanus, usamos MongoDB para:

  • Aplicações com requisitos evolutivos
  • Sistemas que precisam escalar horizontalmente
  • Dados semi-estruturados de APIs externas
  • Real-time features com Change Streams

Se seu projeto precisa de flexibilidade e escala, MongoDB pode ser a escolha certa - e estamos aqui para ajudar.


Quer construir com MongoDB? Nossa equipe tem expertise em modelagem NoSQL e otimização. Fale conosco.

Equipe Arkanus

Equipe Arkanus

Equipe Arkanus escreve sobre tecnologia, transformação digital e engenharia de software na Arkanus.

Compartilhe este artigo

Artigos Relacionados