Node.js: O Guia Essencial Para Devs e Gestores
Node.js revolucionou o desenvolvimento backend com JavaScript. Descubra por que empresas como Netflix, PayPal e Uber confiam nesta tecnologia.
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
27/10/2025
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 é 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 (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: "..." }
]
}
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:
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.
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.
// 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
}
}
});
// 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" }
]);
// 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 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 }
);
// Deletar um
await db.collection('usuarios').deleteOne({
_id: ObjectId("...")
});
// Deletar múltiplos
await db.collection('usuarios').deleteMany({
status: "spam"
});
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
}
Í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");
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
}
}
]);
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 Sets:
┌────────────┐
│ Primary │──┐ Writes
└────────────┘ │
│ │
Replicates │
│ │
├─────────┴─────┬─────────────┐
│ │ │
┌────────────┐ ┌────────────┐ ┌────────────┐
│ Secondary │ │ Secondary │ │ Secondary │
│ (Reads) │ │ (Reads) │ │ (Backup) │
└────────────┘ └────────────┘ └────────────┘
// 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();
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);
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);
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 }
});
// ✅ 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 });
Cloud managed MongoDB da própria MongoDB Inc:
// Connection string Atlas
mongodb+srv://usuario:senha@cluster0.mongodb.net/mydb?retryWrites=true&w=majority
✅ 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
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:
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 escreve sobre tecnologia, transformação digital e engenharia de software na Arkanus.
Node.js revolucionou o desenvolvimento backend com JavaScript. Descubra por que empresas como Netflix, PayPal e Uber confiam nesta tecnologia.
Descubra por que PostgreSQL é a escolha preferida de desenvolvedores para aplicações que exigem confiabilidade, performance e recursos avançados.
Python não é só para cientistas de dados. Descubra como esta linguagem versátil pode transformar seus processos de negócio, desde automação até inteligência artificial.