1. Arquitetura do MongoDB & Storage Engine WiredTiger
O MongoDB armazena dados em documentos BSON organizados em Collections (equivalentes a tabelas no modelo relacional), que por sua vez residem em Databases.
- mongod: O processo servidor primário que gerencia o acesso aos dados, atende requisições de clientes e executa operações em segundo plano.
- Storage Engine (WiredTiger): O mecanismo padrão de armazenamento desde o MongoDB 3.2. É responsável por gerenciar como os dados são gravados em disco e mantidos em memória RAM (Cache WiredTiger).
- Concorrência a Nível de Documento (Document-level Concurrency): Diferente de SGBDs tradicionais ou engines antigas (MMAPv1) que travavam o banco ou a coleção, o WiredTiger utiliza controle de concorrência otimista com locks a nível de documento individual para operações de escrita.
- Compressão de Dados: O WiredTiger aplica compressão Snappy por padrão para coleções e zlib para índices, otimizando o uso de armazenamento em disco e I/O.
2. Operações de Inserção: insertOne() vs insertMany()
No MongoDB Shell (mongosh), a criação de documentos é realizada através das rotinas insertOne() e insertMany().
2.1 insertOne()
Insere um único documento na coleção. Se o campo _id não for fornecido explicitamente, o driver/servidor gera automaticamente um ObjectId de 12 bytes.
db.produtos.insertOne({
nome: "Teclado Mecânico Custom",
categoria: "Periféricos",
preco: 450.00,
estoque: 15,
tags: ["teclado", "rgb", "switches-brown"]
});
2.2 insertMany() e a opção { ordered: true | false }
Insere um array de documentos em lote. Esta opção é um dos pontos mais cobrados no exame de certificação!
// Exemplo de inserção desordenada (unordered)
db.usuarios.insertMany([
{ _id: 1, nome: "Alice" },
{ _id: 2, nome: "Bob" },
{ _id: 2, nome: "Carlos" }, // Erro de Chave Duplicada!
{ _id: 3, nome: "Diana" }
], { ordered: false });
// Resultado com ordered: false -> Alice, Bob e Diana serão inseridos com sucesso. Carlos falhará.
3. Operações de Consulta: find() e findOne()
O método find(query, projection) retorna um Cursor para os documentos que correspondem aos critérios de busca.
3.1 Modificadores do Cursor (Sort, Skip, Limit)
A ordem encadeada de chamadas no shell não altera a ordem de execução do servidor. O MongoDB sempre aplica os modificadores na sequência otimizada:
sort()- Ordena os resultados.skip()- Pula N documentos.limit()- Limita a quantidade máxima de retorno.
// Retorna os 5 produtos mais caros da categoria 'Periféricos', pulando os 2 primeiros
db.produtos.find({ categoria: "Periféricos" })
.sort({ preco: -1 }) // -1 para decrescente, 1 para crescente
.skip(2)
.limit(5);
4. Operadores de Consulta (Query Operators)
4.1 Operadores de Comparação
| Operador | Significado | Exemplo Explicativo |
|---|---|---|
$eq / $ne |
Igual / Diferente | { status: { $ne: "INATIVO" } } |
$gt / $gte |
Maior / Maior ou Igual | { preco: { $gte: 100.00 } } |
$lt / $lte |
Menor / Menor ou Igual | { idade: { $lt: 18 } } |
$in / $nin |
Em / Não contido em array | { cidade: { $in: ["Uberaba", "SP"] } } |
4.2 Operadores Lógicos
$and: Associa múltiplas expressões onde TODAS devem ser verdadeiras. Note que vírgula num objeto JSON é um$andimplícito (ex:{ preco: { $gte: 50 }, estoque: { $gt: 0 } }). O$andexplícito é obrigatório quando a consulta envolve o mesmo campo ou operador repetidamente.$or: Corresponde a documentos que satisfazem pelo menos uma das expressões num array de condições.db.produtos.find({ $or: [ { preco: { $lt: 50 } }, { estoque: 0 } ] });$nor: Retorna documentos que falham em todas as condições fornecidas.$not: Inverte o resultado do operador de consulta especificado.
4.3 Operadores de Elemento
$exists: Verifica a presença (true) ou ausência (false) de um campo específico no documento BSON.$type: Seleciona documentos em que o campo seja do tipo BSON especificado (ex:"string","number","objectId","array"ou seus equivalentes numéricos como2para String).
// Busca documentos que contêm o campo 'desconto' E cujo valor seja do tipo número
db.vendas.find({
desconto: { $exists: true, $type: "number" }
});
5. Projeções (Projections)
A projeção determina quais campos devem ser retornados no documento de resposta. Isso reduz drasticamente a sobrecarga de rede e o consumo de memória RAM.
// VÁLIDO: Projeção de Inclusão (retorna apenas nome, preco e suprime o _id)
db.produtos.find({}, { nome: 1, preco: 1, _id: 0 });
// VÁLIDO: Projeção de Exclusão (retorna todos os campos EXCETO estoque e dataCriacao)
db.produtos.find({}, { estoque: 0, dataCriacao: 0 });
// INVÁLIDO (Gera Erro MongoServerError): Mistura de 1 e 0
db.produtos.find({}, { nome: 1, preco: 0 }); // ERRO!
6. Questões Simuladas para a Certificação
Teste seus conhecimentos com questões reais no padrão da prova oficial MongoDB Associate Developer Exam.
Questão 01:
A coleção clientes atualmente possui 0 documentos. Um desenvolvedor executa o seguinte comando em uma coleção vazia:
db.clientes.insertMany([
{ _id: 10, nome: "Ana" },
{ _id: 20, nome: "Bruno" },
{ _id: 20, nome: "Caio" },
{ _id: 30, nome: "Daniela" }
], { ordered: true });
Qual será o estado da coleção clientes após a execução e qual será o resultado retornado?
Alternativas:
A) Nenhum documento será inserido porque a operação é atômica e falha inteiramente no erro de chave duplicada.
B) Os documentos de Ana (_id: 10) e Bruno (_id: 20) serão inseridos. A operação é interrompida no documento de Caio e Daniela não é inserida.
C) Os documentos de Ana (_id: 10), Bruno (_id: 20) e Daniela (_id: 30) serão inseridos com sucesso.
D) Todos os 4 documentos serão inseridos, com o MongoDB gerando um novo _id automático para Caio.
Ver Gabarito ComentadoResposta Correta: B
Explicação: Por padrão, insertMany possui { ordered: true }. O MongoDB processa os documentos sequencialmente: Ana (_id: 10) é inserida, Bruno (_id: 20) é inserido. Quando chega em Caio (_id: 20), ocorre uma violação de chave primária duplicada. A execução é abortada imediatamente. Daniela (_id: 30) nunca chega a ser processada. A alternativa A está errada porque inserções em lote no MongoDB não rolam de volta (rollback) inserções passadas a menos que estejam explicitamente dentro de uma transação multi-documento ACID.
Questão 02:
Você precisa consultar a coleção pedidos e retornar apenas os campos cliente_id e total, sem incluir o campo _id original do MongoDB. Qual das opções abaixo executa essa tarefa corretamente sem gerar erros de sintaxe?
Alternativas:
A) db.pedidos.find({}, { cliente_id: 1, total: 1, _id: 0 });
B) db.pedidos.find({}, { cliente_id: 1, total: 1, status: 0 });
C) db.pedidos.find({ cliente_id: 1, total: 1 }, { _id: 0 });
D) db.pedidos.find({ projection: { cliente_id: true, total: true, _id: false } });
Resposta Correta: A
Explicação: A alternativa A segue perfeitamente a exceção da regra de ouro das projeções: podemos especificar a inclusão de campos (cliente_id: 1, total: 1) e suprimir explicitamente o _id com _id: 0. A alternativa B tenta misturar inclusão (1) com exclusão (0) de um campo comum (status: 0), o que lança exceção no MongoDB. A alternativa C coloca a projeção no primeiro argumento (filtro de busca) incorretamente.
Questão 03:
Qual das seguintes consultas em mongosh encontra todos os documentos na coleção livros onde o campo preco é menor que 50 OU o campo esgotado NÃO existe?
Alternativas:
A) db.livros.find({ preco: { $lt: 50 }, esgotado: { $exists: false } });
B) db.livros.find({ $or: [ { preco: { $lt: 50 } }, { esgotado: { $exists: false } } ] });
C) db.livros.find({ $and: [ { preco: { $lt: 50 } }, { esgotado: { $type: "null" } } ] });
D) db.livros.find({ preco: { $lt: 50 } }).or({ esgotado: { $exists: false } });
Resposta Correta: B
Explicação: O operador $or espera um array de sub-documentos de expressão. Para a condição "menor que 50 OU não existe", usamos { $or: [ { preco: { $lt: 50 } }, { esgotado: { $exists: false } } ] }. A alternativa A cria uma conjunção lógica E (AND) implícita entre as chaves do objeto JSON. A alternativa D utiliza uma sintaxe encadeada inexistente.
Prévia de Amanhã (Dia 03/15): Operações CRUD - Parte 2: Atualização e Remoção (update, delete, operadores $set, $unset, $inc, $push, $pull).
Bons estudos, dev! Conteúdo gerado especialmente para a sua preparação no MongoDB Associate Developer Exam.