Skip to main content

Mongoshell (mongosh) | MongoDB | Banco de dados

  • Mongoshell (mongosh) | MongoDB | Banco de dados

Documentação: Instalação do Mongosh (Windows e Linux) + Principais Comandos

O que é o Mongosh

O mongosh (MongoDB Shell) é o terminal oficial do MongoDB para conectar em servidores MongoDB e executar consultas, rotinas administrativas e comandos de banco.


1) Pré-requisitos

Para usar o mongosh, você precisa:

  • Um servidor MongoDB disponível (local ou remoto)
  • Rede liberada para conexão (porta padrão: 27017)
  • Credenciais (se o ambiente exigir autenticação)

2) Instalação do Mongosh no Windows

2.1) Instalar via instalador oficial (MSI)

  1. Acesse a página oficial de downloads do MongoDB
  2. Baixe o MongoDB Shell (mongosh) para Windows (.msi)
  3. Execute o instalador
  4. Abra o PowerShell e valide:
mongosh --version

2.2) Ajustar PATH (se o comando não funcionar)

Se o Windows retornar que o comando não existe:

  1. Localize o executável do mongosh, exemplo:

    • C:\Program Files\MongoDB\mongosh\bin\mongosh.exe
  2. Vá em:

    • Configurações avançadas do sistema → Variáveis de Ambiente
  3. Adicione a pasta do mongosh.exe na variável Path

  4. Feche e abra o terminal novamente e teste:

mongosh --version

3) Instalação do Mongosh no Linux

3.1) Ubuntu/Debian (repositório)

  1. Atualize os pacotes:
sudo apt update
  1. Instale dependências comuns:
sudo apt install -y wget gnupg
  1. Instale o mongosh via repositório do MongoDB (recomendado no Linux)

Os comandos exatos podem variar pela sua versão do sistema operacional.

  1. Valide a instalação:
mongosh --version

3.2) Instalação via pacote .deb (alternativa)

  1. Baixe o pacote do mongosh para Debian/Ubuntu (.deb)
  2. Instale com:
sudo dpkg -i mongosh*.deb
sudo apt -f install -y
  1. Valide:
mongosh --version

3.3) RHEL/CentOS/Fedora (via .rpm)

  1. Baixe o pacote do mongosh (.rpm)
  2. Instale com:
sudo rpm -i mongosh*.rpm

ou:

sudo dnf install -y mongosh*.rpm
  1. Valide:
mongosh --version

4) Conexões no Mongosh

4.1) Conectar localmente (padrão)

mongosh

4.2) Conectar em host e porta

mongosh "mongodb://localhost:27017"

4.3) Conectar com usuário e senha

mongosh "mongodb://USUARIO:SENHA@HOST:27017"

4.4) Conectar em um database específico

mongosh "mongodb://localhost:27017/meu_database"

4.5) Conectar com authSource (usuário no admin)

mongosh "mongodb://USUARIO:SENHA@HOST:27017/meu_database?authSource=admin"

4.6) Conectar no MongoDB Atlas (SRV)

mongosh "mongodb+srv://USUARIO:SENHA@cluster0.xxxxx.mongodb.net/meu_database"

5) Comandos Principais do Mongosh

5.1) Ajuda e utilitários

  • Ajuda geral do shell:
help
  • Ajuda do database atual:
db.help()
  • Ajuda de uma collection específica:
db.<collection_name>.help()
  • Ver versão do MongoDB (servidor conectado):
db.version()
  • Sair do mongosh:
exit

6) Navegação entre databases

6.1) Listar bancos disponíveis

show databases

6.2) Ver qual database está em uso

db

6.3) Trocar/criar database

use <database_name>

Exemplo:

use admin

6.4) Apagar o database atual

db.dropDatabase()

⚠️ Remove o banco inteiro.


7) Collections

7.1) Listar collections do database atual

show collections

7.2) Criar collection manualmente

db.createCollection("<collection_name>")

Exemplo:

db.createCollection("users")

7.3) Renomear collection

db.<collection_name>.renameCollection("<new_collection_name>")

Exemplo:

db.users.renameCollection("usuarios")

7.4) Apagar collection

db.<collection_name>.drop()

Exemplo:

db.usuarios.drop()

8) CRUD (Create, Read, Update, Delete)

8.1) Inserir documentos

Inserir um documento (insertOne)

info

O comando db.users.insertOne({}) é aceitável e irá criar um id automatico

db.<collection_name>.insertOne({ <document> })

Exemplo:

db.users.insertOne({ name: "John", age: 30 })

Inserir vários documentos (insertMany)

db.collection.insertMany(
[ <documento1>, <documento2>, ... ],
{
ordered: <boolean>,
writeConcern: <document>,
bypassDocumentValidation: <boolean>,
comment: <any>
}
)
OpçãoTipoPadrãoPara que serve
orderedbooleantrueDefine se o MongoDB deve inserir em ordem e parar no primeiro erro
writeConcerndocumentconfiguração da conexão/collectionDefine o nível de confirmação da escrita
bypassDocumentValidationbooleanfalseIgnora validações de schema da collection
commentqualquer valor BSONAdiciona comentário para rastrear a operação em logs/profiler

Exemplo:

db.users.insertMany([
{ name: "Alice", age: 25 },
{ name: "Bob", age: 35 }
])
  • OBS: Para obter os ids retornados, utilize a propriedade do resultado chamada insertdIds
db.orders.insertMany([
{ customer: "John Smith", product: "Book" },
{ customer: "Jane Doe", product: "Laptop" }
]).insertedIds

Inserir por bulk-write

db.sales.bulkWrite([
// 1. Inserir um documento
{
insertOne: {
document: {
item: "notebook",
quantity: 5,
price: 3500,
category: "electronics"
}
}
},

// 2. Inserir outro documento
{
insertOne: {
document: {
item: "mouse",
quantity: 20,
price: 50,
category: "electronics"
}
}
},

// 3. Atualizar um documento existente
{
updateOne: {
filter: { item: "mouse" },
update: {
$inc: { quantity: 10 }, // aumenta quantidade
$set: { updatedAt: new Date() }
}
}
},

// 4. Atualizar vários documentos
{
updateMany: {
filter: { category: "electronics" },
update: {
$mul: { price: 1.1 } // aumenta preço em 10%
}
}
},

// 5. Deletar um documento
{
deleteOne: {
filter: { item: "old-keyboard" }
}
},

// 6. Deletar vários documentos
{
deleteMany: {
filter: { quantity: { $lte: 0 } }
}
},

// 7. Replace (substitui completamente o documento)
{
replaceOne: {
filter: { item: "notebook" },
replacement: {
item: "notebook",
quantity: 8,
price: 3400,
category: "electronics",
replaced: true
}
}
}
],
{
ordered: false // executa em paralelo (melhor performance)
});

8.2) Consultar documentos

Buscar um documento (findOne)

db.collection.findOne(
<filtro>,
<projecao>,
{
sort: <document>,
maxTimeMS: <number>,
collation: <document>,
comment: <any>,
readConcern: <document>
}
)
info

O findOne() NÃO retorna um cursor, ele traz o documento direto (ou null). Por isso, projeção e ordenação vão no segundo parâmetro (Objeto de Opções).

OpçãoTipoPadrãoPara que serve
filtrodocument{}Define quais documentos podem ser encontrados
projecaodocumentretorna todos os camposDefine quais campos devem aparecer ou ser ocultados no resultado
sortdocumentordem natural da collectionDefine a ordenação antes de escolher o primeiro documento
maxTimeMSnumbersem limite explícitoDefine tempo máximo de execução em milissegundos
collationdocumentcollation padrão da collectionDefine regras de comparação de strings, como case-insensitive e idioma
commentqualquer valor BSONAdiciona comentário para rastrear a operação em logs/profiler
readConcerndocumentconfiguração da conexãoDefine o nível de consistência/leitura esperado na operação

Exemplo:

db.users.findOne(
{ status: "ACTIVE" },
{ name: 1, email: 1, _id: 0 },
{
sort: { createdAt: -1 },
maxTimeMS: 1000,
comment: "buscar_usuario_ativo_mais_recente"
}
)

Esse comando busca um único usuário ativo, retornando apenas name e email, ordenando pelo createdAt mais recente antes de escolher o primeiro documento. O MongoDB trata findOne como uma operação de leitura dentro das operações CRUD.


Buscar vários documentos (find)

danger

find com valores em um array segue a seguinte lógica:

  • ordem igual
  • tamanho igual
  • valores iguais ❗ Ordem importa
db.<collection_name>.find({ <query> })

Exemplo:

db.users.find({ age: { $gt: 25 } })

Projeção (retornar apenas campos específicos)

db.<collection_name>.find(
{ <query> },
{ campo1: 1, campo2: 1, _id: 0 }
)

Exemplo:

db.users.find(
{ age: { $gt: 18 } },
{ name: 1, age: 1, _id: 0 }
)

Ordenação (sort)

db.<collection_name>.find().sort({ <field>: 1 })

Exemplo (ascendente):

db.users.find().sort({ age: 1 })

Exemplo (descendente):

db.users.find().sort({ age: -1 })

Limitar resultados (limit)

db.<collection_name>.find().limit(<n>)

Exemplo:

db.users.find().limit(5)

Paginação (skip + limit)

db.<collection_name>.find().skip(<n>).limit(<n>)

Exemplo:

db.users.find().skip(10).limit(5)

Contar documentos (recomendado)

db.<collection_name>.countDocuments()

Com filtro:

db.<collection_name>.countDocuments({ <query> })

Exemplo:

db.users.countDocuments({ age: { $gt: 25 } })

Tabelas de operadores | mongoshell

  • Operadores de Data (Aggregation)
OperadorDescriçãoExemplo
$yearRetorna o ano da data{ $project: { ano: { $year: "$data" } } }
$monthRetorna o mês (1–12){ $project: { mes: { $month: "$data" } } }
$dayOfMonthRetorna o dia do mês{ $project: { dia: { $dayOfMonth: "$data" } } }
$dayOfWeekRetorna o dia da semana (1–7){ $project: { diaSemana: { $dayOfWeek: "$data" } } }
$dayOfYearRetorna o dia do ano{ $project: { diaAno: { $dayOfYear: "$data" } } }
$hourRetorna a hora{ $project: { hora: { $hour: "$data" } } }
$minuteRetorna os minutos{ $project: { min: { $minute: "$data" } } }
$secondRetorna os segundos{ $project: { seg: { $second: "$data" } } }
$millisecondRetorna milissegundos{ $project: { ms: { $millisecond: "$data" } } }
$dateAddSoma tempo a uma data{ $addFields: { nova: { $dateAdd: { startDate: "$data", unit: "day", amount: 5 } } } }
$dateSubtractSubtrai tempo de uma data{ $addFields: { nova: { $dateSubtract: { startDate: "$data", unit: "day", amount: 5 } } } }
$dateDiffDiferença entre datas{ $addFields: { dias: { $dateDiff: { startDate: "$inicio", endDate: "$fim", unit: "day" } } } }
$dateTruncTrunca a data (ex: início do dia/mês){ $addFields: { trunc: { $dateTrunc: { date: "$data", unit: "month" } } } }
$toDateConverte para tipo Date{ $addFields: { data: { $toDate: "$stringData" } } }
$dateFromStringConverte string para Date{ $addFields: { data: { $dateFromString: { dateString: "$dataStr" } } } }
$dateToStringConverte Date para string{ $project: { data: { $dateToString: { format: "%Y-%m-%d", date: "$data" } } } }
$dateFromPartsCria uma data a partir de partes{ $addFields: { data: { $dateFromParts: { year: 2026, month: 4, day: 23 } } } }
$dateToPartsQuebra a data em partes{ $project: { partes: { $dateToParts: { date: "$data" } } } }
$isoWeekRetorna semana ISO{ $project: { semana: { $isoWeek: "$data" } } }
$isoDayOfWeekDia da semana ISO (1–7){ $project: { dia: { $isoDayOfWeek: "$data" } } }
$isoWeekYearAno ISO{ $project: { anoIso: { $isoWeekYear: "$data" } } }
  • Operadores de Comparação
OperadorDescriçãoExemplo
$eqIgual{ idade: { $eq: 18 } }
$neDiferente{ idade: { $ne: 18 } }
$gtMaior que{ idade: { $gt: 18 } }
$gteMaior ou igual{ idade: { $gte: 18 } }
$ltMenor que{ idade: { $lt: 18 } }
$lteMenor ou igual{ idade: { $lte: 18 } }
$inValor dentro de array{ status: { $in: ["A", "B"] } }
$ninValor fora de array{ status: { $nin: ["A", "B"] } }
info

O uso do operador $in nem sempre é necessário, se houver um array e você quiser validar se tem apenas um valor lá dentro, você pode ir direto na seguinte query:

ONDE tags É UM CAMPO ARRAY

db.products.find({
"category": { "$in": ["Electronics", "Clothing"] },
"tags": "bestseller"
})

- obs: **o `$in` valida se pelo menos existe um dos valores informados**
  • Operadores Lógicos
OperadorDescriçãoExemplo
$andE lógico{ $and: [ { idade: { $gt: 18 } }, { ativo: true } ] }
$orOu lógico{ $or: [ { idade: { $lt: 18 } }, { vip: true } ] }
$notNega condição{ idade: { $not: { $gt: 18 } } }
$norNenhuma condição verdadeira{ $nor: [ { idade: 18 }, { ativo: false } ] }
info

Para fazer um between no Mongo: db.getCollection("movies").find({ runtime: { $gte: 90, $lte: 120 }})

  • Operadores de Elemento
OperadorDescriçãoExemplo
$existsCampo existe{ email: { $exists: true } }
$typeTipo do campo{ idade: { $type: "int" } }
  • Operadores de Avaliação
OperadorDescriçãoExemploObservação
$regexExpressão regular{ nome: { $regex: "^A" } }Busca por padrão de texto simples. Pode usar índice em alguns casos, principalmente prefixado.
$exprPermite usar expressões de agregação dentro do find{ $expr: { $gt: ["$saldo", "$limite"] } }Útil para comparar campos do mesmo documento.
$modBusca por resto de divisão{ idade: { $mod: [5, 0] } }Retorna idades divisíveis por 5.
$textBusca textual tradicional do MongoDB{ $text: { $search: "mongodb" } }Usa text index comum, criado com createIndex({ campo: "text" }).
$whereExecuta JavaScript customizado{ $where: "this.idade > 18" }Evite. Pode ser lento e perigoso. Prefira operadores nativos.
  • Diferença entre $text e $search
RecursoOnde usaÍndice usadoExemploQuando usar
$textDentro do find() ou $matchText index comum do MongoDBdb.posts.find({ $text: { $search: "mongodb" } })Busca textual simples.
$searchDentro do aggregate()Atlas Search indexdb.posts.aggregate([{ $search: { text: { query: "mongodb", path: "title" } } }])Busca avançada no Atlas: relevância, autocomplete, fuzzy, highlight, facets etc.
$regexDentro do find()Índice comum, dependendo do padrãodb.posts.find({ title: { $regex: "^mongo" } })Busca por padrão específico, não full-text search.

Para usar o $text e sua propriedade $search. Primeiro deve criar um index

db.posts.createIndex({ title: "text", content: "text" })
info

$expr permite usar expressões no filtro da query, como comparar campo com campo ou campo com cálculo. Exemplo: { $expr: { $gt: ["$saldo", "$limite"] } } -> Saldo é maior que o limite

  • Operadores de Array
OperadorTipoDescriçãoExemplo
$allQuery OperatorRetorna documentos cujo array contém todos os valores especificados no all. A ordem dos elementos não importa.{ tags: { $all: ["js", "node"] } }
$elemMatchQuery OperatorRetorna documentos onde pelo menos um elemento do array satisfaz múltiplas condições simultaneamente. - Quando você precisa validar múltiplas condições no mesmo elemento de um array.{ notas: { $elemMatch: { $gt: 7, $lt: 9 } } }
$sizeQuery OperatorFiltra documentos cujo array possui exatamente o tamanho informado.{ tags: { $size: 3 } }
$unwindAggregation StageDesconstrói um array, criando um novo documento para cada elemento do array.db.movies.aggregate([{ $unwind: "$genres" }])
  • Observações sobre o $unwind
SituaçãoResultado
Array vazio❌ some
Campo inexistente❌ some
null❌ some
Não-array✅ vira 1 doc
Com preserveNullAndEmptyArrays: true✅ mantém
Valores duplicados✅ mantém
{  
_id: 1,
lname: 'Smith',
tech_stack: [ 'sql', 'git', 'python', 'django' ],
fname: 'Bob'
},

{
_id: 2,
fname: 'Michael',
lname: 'Doe',
tech_stack: [ 'git', 'python', 'linux', 'flask' ]
}

{ $unwind: { path: '$tech_stack' }}
// vira 8 documentos
  • Operadores de Atualização
OperadorDescriçãoExemplo
$setDefine/atualiza valor - cria o campo se ele não existir.{ $set: { nome: "Carlos" } }
$unsetRemove campos do documento. Funciona com campos aninhados, pode ser usado em updates e aggregation (stage), e é equivalente a $project quando usado para excluir campos{ $unset: { idade: "" } } -> pode ser usado "" e 1
$incIncrementa - você passa o valor que deve ser incrementado no valor atual do campo{ $inc: { saldo: 100 } }
$mulMultiplica - você passa o valor que deve ser multiplicado no valor atual do campo{ $mul: { saldo: 2 } }
$renameRenomeia campo{ $rename: { nome: "nomeCompleto" } }
$setOnInsertDefine apenas no insert (upsert){ $setOnInsert: { criadoEm: new Date() } }
$minAtualiza se valor atual for maior{ $min: { idade: 18 } }
$maxAtualiza se valor atual for menor{ $max: { idade: 65 } }
$currentDateAtualiza com data atual{ $currentDate: { atualizadoEm: true } }

Sobre o $unset

AfirmaçãoCorretaExplicação
Não lança erro se o campo não existirSim$unset ignora campos inexistentes, sem falhar
Pode ser usado com aggregate e updateManySimFunciona tanto em pipelines quanto em operações de update
Pode ser equivalente ao $project ao remover/excluir campoSim$project pode excluir campos (0), similar ao efeito do $unset
Remove/exclui campos dos documentosSimFunção principal do $unset é remover campos

Sobre o $setOnInsert

  db.inventory.updateOne(
{ item: "notebook" },
{ $inc: { quantity: 10 }, $setOnInsert: { price: 5.99 } },
{ upsert: true }
)

Esse comando faz o seguinte, altera o documento e incrementa 10 na quantidade, caso o campo não exista, eu especifico um preço que eu quero caso precise inserir o campo quantidade

Sobre o upsert

No UpdateOne, o upsert: true garante isto:

Se nenhum documento for encontrado pelo filtro, o MongoDB cria um novo documento usando a combinação do filtro + os operadores de update aplicáveis. Ex:

  db.users.updateOne(
{ email: "ana@email.com" },
{
$set: {
nome: "Ana",
ativo: true
}
},
{ upsert: true }
)
  • Se já existir, atualiza para:
    • { email: "ana@email.com", nome: "Ana", ativo: true }
  • Se não:
    • {_id: ObjectId("..."), email: "ana@email.com", nome: "Ana", ativo: true}
  • Operadores de Array (Update)
OperadorDescriçãoExemplo
$pushAdiciona no array (pode duplicar valores){ $push: { tags: "novo" } }
$addToSetAdiciona se não existir{ $addToSet: { tags: "novo" } }
$pullRemove do array{ $pull: { tags: "antigo" } }
$popRemove primeiro ou último. Use 1 ou -1{ $pop: { tags: 1 } }
$pullAllRemove múltiplos valores{ $pullAll: { tags: ["a", "b"] } }
$eachModificador para múltiplos valores{ $push: { tags: { $each: ["a", "b"] } } }
$positionDefine posição no push{ $push: { tags: { $each: ["x"], $position: 0 } } }
$sliceLimita tamanho do array{ $push: { tags: { $each: ["x"], $slice: 5 } } }
$Atualiza o primeiro elemento que corresponde{ $set: { "tags.$": "novo" } }
$[]Atualiza todos os elementos do array{ $set: { "tags.$[]": "novo" } }
$[<id>]Atualiza elementos com filtro{ $set: { "tags.$[elem]": "novo" } } + arrayFilters

$slice

Update (controle de tamanho do array):

db.posts.updateOne(
{ _id: 1 },
{
$push: {
comments: {
$each: [novoComentario],
$slice: -100
}
}
}
)
  • adiciona o novo comentário
  • mantém apenas os últimos 100
  • evita crescimento infinito do array

Find (projeção de array):

db.posts.find(
{},
{ comments: { $slice: 3 } }
)

Formas do $slice no find:

  • $slice: 3 → primeiros 3
  • $slice: -3 → últimos 3
  • $slice: [1, 2] → pula 1, pega 2

⚠️ Só funciona na projeção, não no filtro

  • Operadores de Condição
OperadorDescriçãoExemplo
$condExecuta uma condição estilo if / else{ $cond: [ { $gte: ["$nota", 7] }, "Aprovado", "Reprovado" ] }
$ifNullRetorna um valor alternativo quando o campo é null ou não existe{ $ifNull: ["$apelido", "$nome"] }
$switchExecuta múltiplas condições, parecido com switch/case ou if/else if{ $switch: { branches: [...], default: "Outro" } }
  • Pode ser usado dentro de $project, $addFields, $set, $group, entre outros stages.

  • Operadores de Projeção

OperadorDescriçãoExemplo
$Primeiro elemento que bate na query{ "notas.$": 1 }
$elemMatchProjeta elemento específico{ notas: { $elemMatch: { $gt: 7 } } }
$metaMetadado (ex: score texto){ score: { $meta: "textScore" } }
  • Operadores Match
OperadorDescriçãoExemplo
$matchFiltra documentos no pipeline (equivalente ao WHERE). Deve ser usado o mais cedo possível no pipeline. Possui sintaxe semelhante ao find() e pode ser usado múltiplas vezes.{ $match: { status: "A" } }
$elemMatchGarante que múltiplas condições sejam aplicadas no mesmo item do array{ notas: { $elemMatch: { $gt: 7, $lt: 10 } } }
  • Outros

    • Distinct: db.getCollection("movies").distinct("languages")

8.3) Atualizar documentos

Atualizar um documento (updateOne)

db.<collection_name>.updateOne(
{ <query> },
{ $set: { <field>: <value> } }
)

Exemplo:

db.users.updateOne(
{ name: "John" },
{ $set: { age: 31 } }
)
danger

Cuidade, usar o updateOne sem o $set faz com que atualize o documento inteiro. Sem $set vira Replacement update.

Sem o set antes de atualizar:

db.users.updateOne(
{ _id: 1 },
{ name: "Carlos" }
)


{
_id: 1,
name: "João",
age: 30,
email: "joao@email.com",
active: true
}

Depois de atualizar sem o set

{
_id: 1,
name: "Carlos",
}

o _id é preservado

Métodos find and modify

MétodoStatusOperaçãoRetorno padrãoOpção para retornar atualizadoUso recomendado
findAndModify❌ Legadofind + update/deleteDocumento antes da alteraçãonew: trueEvitar (compatibilidade apenas)
findOneAndUpdate✅ Atualfind + updateDocumento antesreturnDocument: "after"✔️ Principal uso
findOneAndReplace✅ Atualfind + replaceDocumento antesreturnDocument: "after"✔️ Substituição total
findOneAndDelete✅ Atualfind + deleteDocumento deletado❌ Não aplicável✔️ Remoção controlada
  • Exemplo findAndModify
db.medications.findAndModify({ query: { status: "in-stock" }, update: { $set: { status: "high-demand" }, $inc: { stock: 10 } }})
warning

Repare que é necessário especificar a palavra query e update o que nos métodos mais atuais não é necessário. Esse comando é genêrico e aceita várias operações, como:

{
query: ..., // qual documento encontrar
sort: ..., // se encontrar vários, qual escolher
update: ..., // como atualizar
remove: ..., // ou remover
new: ..., // retornar antes ou depois
upsert: ...
}
db.orders.findAndModify({
query: { status: "Pending" },
update: { $set: { status: "Completed" } }
})
info

O método findAndModify realiza a busca e a alteração atomicamente evitando concorrência. De outra forma nós teriamos que realizar o find() e depois o update()

A propriedade new significa:

  • new: false → retorna o documento antes da alteração
  • new: true → retorna o documento depois da alteração

CUIDADO

db.orders.findAndModify({
query: { _id: 1 },
update: { status: "completed", quantity: 60 },
new: true
});
  • Dessa forma, o update não está usando nenhum operador como o $set e por isso da forma que está ele vai transformar o documente deixando apenas os dois campos que está dentro do update. Exemplo:

  • Antes

{
_id: 1,
customer: "João",
status: "pending",
quantity: 10,
total: 500
}
  • Depois
{
_id: 1,
status: "completed",
quantity: 60
}

Atualizar vários documentos (updateMany)

db.collection.updateMany(
<filter>,
<update>,
{
upsert: <boolean>,
writeConcern: <document>,
collation: <document>,
arrayFilters: [ <filterdocument1>, ... ],
hint: <document|string>,
let: <document>,
comment: <any>
}
)


db.students.updateMany(
{},
{ $inc: { "exams.$[elem].score": 5 } },
{ arrayFilters: [ { "elem.score": { $lt: 90 } } ] }
);

// {} -> Busca todos os elementos
// { $inc: { "exams.$[elem].score": 5 } } -> $[elem] em cada elemento do array
// { arrayFilters: [ { "elem.score": { $lt: 90 } } ] } -> array filter
OpçãoTipoPadrãoPara que serve
upsertbooleanfalseSe não encontrar documento, cria um novo
writeConcerndocumentconfiguração da conexão/collectionDefine o nível de confirmação da escrita
collationdocumentDefine regras de comparação de string, como case-insensitive
arrayFiltersarrayFiltra quais itens de um array serão atualizados
hintdocument/stringForça o uso de um índice específico
letdocumentDeclara variáveis para usar na operação
commentqualquer valor BSONAdiciona comentário para profiler/logs

Exemplo:

db.users.updateMany(
{ active: { $exists: false } },
{ $set: { active: true } }
)

Substituir documento inteiro (replaceOne)

db.collection.replaceOne(
<filtro>,
<novo_documento>,
{
upsert: <boolean>,
writeConcern: <document>,
collation: <document>,
hint: <document|string>,
let: <document>,
sort: <document>
}
)
OpçãoTipoPadrãoPara que serve
filtrodocumentobrigatórioDefine qual documento será substituído
novo_documentodocumentobrigatórioNovo documento que substituirá o documento encontrado
upsertbooleanfalseCria um novo documento se nenhum documento bater com o filtro
writeConcerndocumentconfiguração da conexão/collectionDefine o nível de confirmação da escrita
collationdocumentcollation padrão da collectionDefine regras de comparação de strings, como idioma e case-insensitive
hintdocument ou stringForça o uso de um índice específico
letdocumentDefine variáveis que podem ser usadas na operação
sortdocumentordem natural da collectionDefine qual documento substituir quando mais de um documento bater no filtro

Exemplo:

db.users.replaceOne(
{ name: "John" },
{ name: "John", age: 31, active: true },
{
upsert: false,
writeConcern: { w: "majority" },
comment: "substituir_usuario_john"
}
)

Ponto importante:

db.users.replaceOne(
{ name: "John" },
{ age: 31 }
)

Nesse caso, o documento antigo será substituído por:

{
_id: ObjectId("..."),
age: 31
}

Ou seja: campos antigos como name, email, active, etc. serão removidos se não estiverem no novo documento.

findOneAndDelete

O findOneAndDelete busca um documento, remove esse documento da collection e retorna o documento que foi removido.

Ele é útil quando você precisa deletar e ainda saber exatamente qual documento foi excluído.

db.<collection_name>.findOneAndDelete(
{ <filtro> },
{
projection: <document>,
sort: <document>,
maxTimeMS: <number>,
collation: <document>
}
)
OpçãoTipoPadrãoPara que serve
filtrodocumentobrigatórioDefine qual documento será encontrado e removido
projectiondocumenttodos os camposDefine quais campos retornar do documento removido
sortdocumentordem naturalDefine qual documento remover se vários baterem com o filtro
maxTimeMSnumbersem limite explícitoDefine tempo máximo de execução em milissegundos
collationdocumentcollation padrão da collectionDefine regras de comparação de strings, como idioma e case-insensitive

Exemplo:

db.users.findOneAndDelete(
{ name: "John" }
)

Nesse caso, o MongoDB:

  1. procura o primeiro usuário com name: "John";
  2. remove esse documento;
  3. retorna o documento removido.

Exemplo com sort

db.sessions.findOneAndDelete(
{ userId: 1, status: "expired" },
{
sort: { createdAt: 1 }
}
)

Esse exemplo remove a sessão expirada mais antiga do usuário.

Exemplo com projection
db.users.findOneAndDelete(
{ email: "john@email.com" },
{
projection: {
name: 1,
email: 1,
_id: 0
}
}
)

Remove o documento, mas retorna apenas name e email.

C# Driver
var filter = Builders<User>.Filter.Eq(x => x.Name, "John");

var deletedUser = await collection.FindOneAndDeleteAsync(filter);

Com sort:

var filter = Builders<Session>.Filter.And(
Builders<Session>.Filter.Eq(x => x.UserId, 1),
Builders<Session>.Filter.Eq(x => x.Status, "expired")
);

var options = new FindOneAndDeleteOptions<Session>
{
Sort = Builders<Session>.Sort.Ascending(x => x.CreatedAt)
};

var deletedSession = await collection.FindOneAndDeleteAsync(filter, options);
Diferença rápida
MétodoRemove documento?Retorna documento removido?Uso principal
deleteOneSimNãoRemover um documento
deleteManySimNãoRemover vários documentos
findOneAndDeleteSimSimRemover e obter o documento removido

findOneAndUpdate

O findOneAndUpdate busca um documento, aplica uma atualização e pode retornar o documento antes ou depois da alteração.

Ele é útil quando você precisa fazer uma atualização e já obter o documento atualizado na mesma operação.

db.<collection_name>.findOneAndUpdate(
{ <filtro> },
{ <update> },
{
returnDocument: "before" | "after",
upsert: <boolean>,
projection: <document>,
sort: <document>
}
)
OpçãoTipoPadrãoPara que serve
filtrodocumentobrigatórioDefine qual documento será encontrado
updatedocumentobrigatórioDefine a alteração a ser aplicada
returnDocumentstring"before"Define se retorna o documento antes ou depois da alteração
upsertbooleanfalseCria o documento se nenhum for encontrado
projectiondocumenttodos os camposDefine quais campos retornar
sortdocumentordem naturalDefine qual documento atualizar se vários baterem com o filtro

Exemplo:

db.users.findOneAndUpdate(
{ name: "John" },
{
$set: {
age: 31,
active: true
}
},
{
returnDocument: "after"
}
)

Nesse caso, o MongoDB:

  1. procura o usuário com name: "John";
  2. atualiza age e active;
  3. retorna o documento depois da alteração.
Exemplo com upsert
db.users.findOneAndUpdate(
{ email: "john@email.com" },
{
$set: {
name: "John",
active: true
}
},
{
upsert: true,
returnDocument: "after"
}
)

Se não existir usuário com esse email, o MongoDB cria um novo documento.

C# Driver
var filter = Builders<User>.Filter.Eq(x => x.Name, "John");

var update = Builders<User>.Update
.Set(x => x.Age, 31)
.Set(x => x.Active, true);

var options = new FindOneAndUpdateOptions<User>
{
ReturnDocument = ReturnDocument.After
};

var user = await collection.FindOneAndUpdateAsync(
filter,
update,
options
);
Diferença rápida
MétodoRetorna documento?Uso principal
updateOneNãoAtualizar um documento
findOneAndUpdateSimAtualizar e obter o documento
replaceOneNãoSubstituir o documento inteiro
findOneAndReplaceSimSubstituir e obter o documento

8.4) Remover documentos

Remover um documento (deleteOne)

db.<collection_name>.deleteOne({ <query> })

Exemplo:

db.users.deleteOne({ name: "Alice" })

Remover vários documentos (deleteMany)

db.<collection_name>.deleteMany({ <query> })

Exemplo:

db.users.deleteMany({ active: false })
// deletando documentos onde o array contém um valor
db.users.deleteMany({ tags: "inactive" })
// deletando documentos com condição dentro de array (objetos)
db.orders.deleteMany({
items: { $elemMatch: { product: "mouse", quantity: { $lte: 0 } } }
})

db.orders.deleteMany(
{ "items.product": "Mouse" }
)

info

Quando o documento é deletado o index associado ao documento é removido imediatamente


9) Indexação

9.1) Criar índice

db.<collection_name>.createIndex({ <field>: <1 | -1> })

Exemplo:

db.users.createIndex({ name: 1 })

9.2) Listar índices

db.<collection_name>.getIndexes()

Exemplo:

db.users.getIndexes()

9.3) Remover índice

db.<collection_name>.dropIndex("<index_name>")

Exemplo:

db.users.dropIndex("name_1")

10) Aggregation (Pipeline)


O Aggregation Framework do MongoDB permite processar dados através de um pipeline composto por múltiplos estágios. Cada estágio recebe documentos, transforma e passa para o próximo.


Estrutura do Pipeline

aggregate

O aggregate executa um pipeline de agregação, ou seja, uma sequência de etapas para filtrar, transformar, agrupar, ordenar e calcular dados dentro do MongoDB.

Ele é parecido com um SELECT mais avançado do SQL, podendo fazer operações como WHERE, GROUP BY, ORDER BY, JOIN, projeções e cálculos.

db.<collection_name>.aggregate(
[
{ <stage1> },
{ <stage2> },
{ <stage3> }
],
{
allowDiskUse: <boolean>,
maxTimeMS: <number>,
collation: <document>,
comment: <any>
}
)
OpçãoTipoPadrãoPara que serve
pipelinearrayobrigatórioLista de estágios executados em sequência
allowDiskUsebooleanfalsePermite usar disco em operações pesadas, como sort/group grandes
maxTimeMSnumbersem limite explícitoDefine tempo máximo de execução em milissegundos
collationdocumentcollation padrão da collectionDefine regras de comparação de strings
commentqualquer valor BSONAdiciona comentário para rastrear a operação em logs/profiler
Exemplo básico
db.orders.aggregate([
{
$match: {
status: "paid"
}
},
{
$group: {
_id: "$customerId",
total: { $sum: "$amount" },
quantity: { $sum: 1 }
}
},
{
$sort: {
total: -1
}
}
])

Nesse caso, o MongoDB:

  1. filtra pedidos com status: "paid";
  2. agrupa por customerId;
  3. soma o valor dos pedidos em total;
  4. conta quantos pedidos existem por cliente;
  5. ordena do maior total para o menor.
Principais estágios
EstágioPara que serveExemplo
$matchFiltra documentos{ $match: { active: true } }
$projectDefine/remodela campos retornados{ $project: { name: 1, email: 1 } }
$addFields / $setAdiciona ou recalcula campos{ $addFields: { total: { $sum: "$items.price" } } }
$groupAgrupa documentos e calcula métricas{ $group: { _id: "$status", total: { $sum: 1 } } }
$sortOrdena documentos{ $sort: { createdAt: -1 } }
$limitLimita quantidade de resultados{ $limit: 10 }
$skipPula documentos{ $skip: 20 }
$unwindDesmonta array em vários documentos{ $unwind: "$items" }
$lookupFaz join com outra collection{ $lookup: { from: "users", localField: "userId", foreignField: "_id", as: "user" } }
$outSalva resultado em outra collection{ $out: "resultado" }
$mergeInsere/atualiza em outra collection{ $merge: "resumo_vendas" }
Exemplo com $match e $project
db.users.aggregate([
{
$match: {
active: true
}
},
{
$project: {
_id: 0,
name: 1,
email: 1
}
}
])

Retorna apenas usuários ativos, mostrando somente name e email.

Exemplo com $unwind
db.orders.aggregate([
{
$unwind: "$items"
},
{
$project: {
customerId: 1,
product: "$items.name",
price: "$items.price"
}
}
])

Se um pedido tem vários itens, o $unwind transforma cada item em um documento separado no resultado.

C# Driver
var result = await collection.Aggregate()
.Match(x => x.Status == "paid")
.Group(
x => x.CustomerId,
g => new
{
CustomerId = g.Key,
Total = g.Sum(x => x.Amount),
Quantity = g.Count()
}
)
.SortByDescending(x => x.Total)
.ToListAsync();

Também pode ser feito com BsonDocument:

var pipeline = new[]
{
new BsonDocument("$match", new BsonDocument("status", "paid")),
new BsonDocument("$group", new BsonDocument
{
{ "_id", "$customerId" },
{ "total", new BsonDocument("$sum", "$amount") },
{ "quantity", new BsonDocument("$sum", 1) }
}),
new BsonDocument("$sort", new BsonDocument("total", -1))
};

var result = await collection.Aggregate<BsonDocument>(pipeline).ToListAsync();
Diferença rápida
MétodoUso principal
findBuscar documentos simples
findOneBuscar um único documento
aggregateFiltrar, transformar, agrupar e calcular dados
countDocumentsContar documentos
distinctRetornar valores únicos de um campo
Resumo

Use aggregate quando o find não for suficiente.

Exemplos de uso:

db.orders.aggregate([
{ $match: { status: "paid" } },
{ $group: { _id: "$customerId", total: { $sum: "$amount" } } }
])

O pipeline sempre executa de cima para baixo: a saída de um estágio vira a entrada do próximo.

Fluxo

[documentos] → stage → stage → stage → resultado

Filtragem e Seleção

  • $match → filtra documentos (equivalente ao WHERE)
  • $limit → limita quantidade
  • $skip → ignora documentos
  • $sample → retorna documentos aleatórios : { $sample: { size: 10 } }
db.users.aggregate([
{ $match: { age: { $gt: 18 } } },
{ $limit: 5 }
])

Transformação de Dados

  • $project → seleciona ou transforma campos
  • $addFields / $set → adiciona campos
  • $unset → remove campos
  • $replaceRoot / $replaceWith → substitui documento

OperadorO que fazStatus
$addFieldsAdiciona ou sobrescreve camposOriginal
$setMesmo comportamento do $addFieldsAlias (recomendado moderno)
  • Se o campo já existe → sobrescreve
  • Se o campo não existe → cria
info
db.players.aggregate([
{
$addFields: {
total_score: { $sum: "$scores" },
avg_score: { $avg: "$scores" }
}
},
{
$addFields: {
total_score_with_bonus: { $add: ["$total_score", "$bonus"] }
}
}
])
  • Podemos ter mais de um addFields, no caso acima o segundo addFields depende do primeiro
    • Referência dos campos já existente se usa o $

db.users.aggregate([
{ $project: { name: 1, idade: "$age" } }
])

Agrupamento e Métricas

  • $group → agrupa documentos (tipo GROUP BY)
  • $count → conta documentos
  • $sortByCount → agrupa + conta automaticamente
        db.produtos.aggregate([
    { $sortByCount: "$categoria" }
    ])

    //saída possível
    /*
    [
    { _id: "Eletrônicos", count: 10 },
    { _id: "Roupas", count: 7 },
    { _id: "Livros", count: 3 }
    ]
    */
db.orders.aggregate([
{
$group: {
_id: "$status",
total: { $sum: 1 }
}
}
])

Ordenação

  • $sort → ordena documentos
db.users.aggregate([
{ $sort: { age: -1 } }
])
  • $sort com campos de array

Podemo usar da seguinte forma

 db.collection.find().sort({ "campoArray": 1 })

ou acessando o valor dos elementos dentro do array. Exemplo: 0,1,2,3,4,5

 db.collection.find().sort({ "campoArray.0": 1 })

Arrays

  • $unwind → transforma cada item do array em um documento
db.users.aggregate([
{ $unwind: "$hobbies" }
])

Relacionamentos

MongoDB suporta relacionamento via aggregation, mas não é o padrão principal (prefira embed quando possível).


$lookup (join simples)

warning

Em um sharded collection o estágio $lookup pode causar tráfego significativo de rede e atrasos no processamento se não for usado com cuidado em coleções com sharding.

Faz join entre coleções (similar a LEFT JOIN):

db.orders.aggregate([
{
$lookup: {
from: "users",
localField: "userId",
foreignField: "_id",
as: "user"
}
}
])
  • Retorna array
  • Use $unwind se quiser objeto
  • Melhor usar com índice no campo relacionado
  • Pode usar pipeline para filtros mais complexos

$graphLookup (join recursivo)

Usado para hierarquia/grafos (ex: organograma, categorias):

db.employees.aggregate([
{
$graphLookup: {
from: "employees",
startWith: "$_id",
connectFromField: "_id",
connectToField: "managerId",
as: "subordinates"
}
}
])
  • Faz busca recursiva
  • Use maxDepth para limitar
  • Use só quando realmente precisar (mais pesado)

Resumo rápido

  • $lookup → relacionamento simples entre coleções
  • $graphLookup → relacionamento recursivo (árvore/grafo)
  • Evite excesso → pode indicar modelagem ruim

Saída de Dados

  • $out → salva resultado em coleção
  • $merge → insere/atualiza em coleção destino

`$out

`

db.users.aggregate([
{ $match: { active: true } },
{ $out: "active_users" }
])

Também é possível enviar a saída para outro banco:

db.getSiblingDB("mdb").coll.aggregate([
{
$out: {
db: "test",
coll: "results"
}
}
])

$merge

O $merge é um estágio do aggregate usado para gravar o resultado do pipeline em outra collection.

Ele pode:

AçãoDescrição
InserirCria documentos que ainda não existem no destino
AtualizarAtualiza documentos já existentes
SubstituirSubstitui documentos existentes
MesclarJunta campos novos com documentos existentes
IgnorarIgnora documentos que já existem
FalharGera erro em caso de conflito
Sintaxe
db.<collection_name>.aggregate([
{ <stage1> },
{ <stage2> },
{
$merge: {
into: "<collection_destino>",
on: "<campo_chave>",
whenMatched: "<acao_quando_encontrar>",
whenNotMatched: "<acao_quando_nao_encontrar>"
}
}
])
CampoPara que serve
intoCollection onde o resultado será gravado
onCampo usado para comparar documento de origem com destino
whenMatchedO que fazer quando já existe documento com a mesma chave
whenNotMatchedO que fazer quando não existe documento com a mesma chave
Exemplo básico

Collection orders:

db.orders.insertMany([
{ _id: 1, customerId: 10, status: "paid", amount: 100 },
{ _id: 2, customerId: 10, status: "paid", amount: 200 },
{ _id: 3, customerId: 20, status: "paid", amount: 50 }
])

Agregação com $merge:

db.orders.aggregate([
{
$match: {
status: "paid"
}
},
{
$group: {
_id: "$customerId",
totalAmount: { $sum: "$amount" },
totalOrders: { $sum: 1 }
}
},
{
$merge: {
into: "customer_summary",
on: "_id",
whenMatched: "merge",
whenNotMatched: "insert"
}
}
])

Resultado gravado em customer_summary:

[
{
_id: 10,
totalAmount: 300,
totalOrders: 2
},
{
_id: 20,
totalAmount: 50,
totalOrders: 1
}
]

Opções do whenMatched

ValorComportamento
replaceSubstitui o documento existente pelo novo
mergeMescla os campos do novo documento com o existente
keepExistingMantém o documento existente e ignora o novo
failGera erro se já existir documento com a mesma chave
pipelineUsa um pipeline customizado para atualizar o documento
Opções do whenNotMatched
ValorComportamento
insertInsere o documento se não existir
discardDescarta o documento se não existir
failGera erro se não existir documento correspondente
Exemplo com replace
db.orders.aggregate([
{
$group: {
_id: "$customerId",
totalAmount: { $sum: "$amount" }
}
},
{
$merge: {
into: "customer_summary",
on: "_id",
whenMatched: "replace",
whenNotMatched: "insert"
}
}
])

Se já existir um documento em customer_summary com o mesmo _id, ele será substituído inteiro pelo novo resultado.

Exemplo com merge
db.orders.aggregate([
{
$group: {
_id: "$customerId",
totalAmount: { $sum: "$amount" }
}
},
{
$merge: {
into: "customer_summary",
on: "_id",
whenMatched: "merge",
whenNotMatched: "insert"
}
}
])

Se já existir:

{
_id: 10,
name: "Adolfo",
totalAmount: 100
}

E o pipeline gerar:

{
_id: 10,
totalAmount: 300
}

Resultado com merge:

{
_id: 10,
name: "Adolfo",
totalAmount: 300
}

O campo name foi mantido, e totalAmount foi atualizado.

Exemplo com keepExisting
db.orders.aggregate([
{
$group: {
_id: "$customerId",
totalAmount: { $sum: "$amount" }
}
},
{
$merge: {
into: "customer_summary",
on: "_id",
whenMatched: "keepExisting",
whenNotMatched: "insert"
}
}
])

Se o documento já existir no destino, ele não será alterado.

Exemplo com discard
db.orders.aggregate([
{
$group: {
_id: "$customerId",
totalAmount: { $sum: "$amount" }
}
},
{
$merge: {
into: "customer_summary",
on: "_id",
whenMatched: "merge",
whenNotMatched: "discard"
}
}
])

Se o documento não existir no destino, ele será descartado.

Exemplo usando collection em outro database
db.orders.aggregate([
{
$group: {
_id: "$customerId",
totalAmount: { $sum: "$amount" }
}
},
{
$merge: {
into: {
db: "reports",
coll: "customer_summary"
},
on: "_id",
whenMatched: "merge",
whenNotMatched: "insert"
}
}
])
C# Driver com BsonDocument
var pipeline = new[]
{
new BsonDocument("$match", new BsonDocument("status", "paid")),
new BsonDocument("$group", new BsonDocument
{
{ "_id", "$customerId" },
{ "totalAmount", new BsonDocument("$sum", "$amount") },
{ "totalOrders", new BsonDocument("$sum", 1) }
}),
new BsonDocument("$merge", new BsonDocument
{
{ "into", "customer_summary" },
{ "on", "_id" },
{ "whenMatched", "merge" },
{ "whenNotMatched", "insert" }
})
};

await collection.Aggregate<BsonDocument>(pipeline).ToListAsync();
Diferença entre $merge e $out
EstágioComportamento
$outSubstitui completamente a collection destino
$mergeInsere, atualiza ou mescla documentos na collection destino

Exemplo:

{ $out: "customer_summary" }

Substitui a collection inteira.

{
$merge: {
into: "customer_summary",
on: "_id",
whenMatched: "merge",
whenNotMatched: "insert"
}
}

Atualiza/inclui documentos sem necessariamente apagar tudo.

Resumo
PontoExplicação
$mergeGrava o resultado do aggregate em uma collection
intoCollection destino
onCampo usado para identificar documentos iguais
whenMatchedAção quando o documento já existe
whenNotMatchedAção quando o documento ainda não existe
Uso comumMaterialized views, relatórios, resumos e sincronização de dados

Pipeline Avançado

  • $facet → múltiplos pipelines paralelos
  • $bucket → agrupa por intervalos definidos
  • $bucketAuto → cria intervalos automaticamente
db.products.aggregate([
{
$bucket: {
groupBy: "$price",
boundaries: [0, 100, 500, 1000],
default: "outros",
output: {
count: { $sum: 1 }
}
}
}
])

$facet

O $facet é um estágio do aggregate que permite executar vários pipelines em paralelo sobre o mesmo conjunto de documentos.

Ele é útil quando você quer gerar várias visões do mesmo resultado em uma única consulta.

Exemplo clássico:

db.products.aggregate([
{
$facet: {
porCategoria: [
{
$group: {
_id: "$category",
total: { $sum: 1 }
}
}
],
precoMedio: [
{
$group: {
_id: null,
media: { $avg: "$price" }
}
}
],
maisCaros: [
{ $sort: { price: -1 } },
{ $limit: 5 }
]
}
}
])

Nesse exemplo, o MongoDB executa três pipelines ao mesmo tempo:

FacetO que faz
porCategoriaAgrupa produtos por categoria
precoMedioCalcula o preço médio geral
maisCarosRetorna os 5 produtos mais caros

Resultado aproximado:

{
porCategoria: [
{ _id: "notebook", total: 10 },
{ _id: "mouse", total: 25 }
],
precoMedio: [
{ _id: null, media: 350.75 }
],
maisCaros: [
{ name: "Notebook Gamer", price: 8000 },
{ name: "Monitor 4K", price: 3500 }
]
}
Exemplo com filtro antes do $facet

Normalmente você usa $match antes do $facet para reduzir os documentos processados:

db.products.aggregate([
{
$match: {
active: true
}
},
{
$facet: {
porCategoria: [
{
$group: {
_id: "$category",
total: { $sum: 1 }
}
}
],
faixaDePreco: [
{
$bucket: {
groupBy: "$price",
boundaries: [0, 100, 500, 1000, 5000],
default: "acima de 5000",
output: {
total: { $sum: 1 }
}
}
}
]
}
}
])

Aqui o MongoDB primeiro filtra os produtos ativos e depois gera duas análises:

PipelineFunção
porCategoriaTotal por categoria
faixaDePrecoTotal por faixa de preço
C# Driver com BsonDocument
var pipeline = new[]
{
new BsonDocument("$match", new BsonDocument("active", true)),
new BsonDocument("$facet", new BsonDocument
{
{
"porCategoria", new BsonArray
{
new BsonDocument("$group", new BsonDocument
{
{ "_id", "$category" },
{ "total", new BsonDocument("$sum", 1) }
})
}
},
{
"maisCaros", new BsonArray
{
new BsonDocument("$sort", new BsonDocument("price", -1)),
new BsonDocument("$limit", 5)
}
}
})
};

var result = await collection
.Aggregate<BsonDocument>(pipeline)
.ToListAsync();
Quando usar $facet

Use $facet quando você precisa retornar vários resultados agregados na mesma consulta.

Exemplos:

CenárioUso
Tela de e-commerceprodutos + filtros por categoria + faixa de preço
Dashboardtotal por status + média + ranking
Relatórioagrupamentos diferentes sobre os mesmos dados
Paginação com totallista paginada + contagem total
Exemplo para paginação com total
db.products.aggregate([
{
$match: {
active: true
}
},
{
$facet: {
data: [
{ $skip: 0 },
{ $limit: 10 }
],
total: [
{ $count: "count" }
]
}
}
])

Resultado:

{
data: [
{ _id: 1, name: "Mouse", active: true },
{ _id: 2, name: "Teclado", active: true }
],
total: [
{ count: 120 }
]
}
Resumo
PontoExplicação
$facetExecuta múltiplos pipelines dentro do mesmo aggregate
EntradaTodos os pipelines recebem os mesmos documentos de entrada
SaídaRetorna um documento com arrays, um para cada facet
Melhor práticaUsar $match antes para reduzir o volume processado
Uso comumDashboards, filtros, relatórios e paginação com total

$bucket

O $bucket é um estágio do aggregate usado para agrupar documentos em faixas de valores.

Ele é muito usado para criar agrupamentos por intervalo, como:

ExemploFaixas
Preço de produtos0-100, 100-500, 500-1000
Idade de usuários0-18, 18-30, 30-60
Valor de pedidos0-50, 50-200, 200-1000
Sintaxe
db.<collection_name>.aggregate([
{
$bucket: {
groupBy: "$<campo>",
boundaries: [<valor1>, <valor2>, <valor3>],
default: "<grupo_padrao>",
output: {
<campo_saida>: { <acumulador>: <expressao> }
}
}
}
])
CampoPara que serve
groupByCampo usado para definir em qual faixa o documento entra
boundariesLimites das faixas
defaultGrupo usado quando o valor não se encaixa em nenhuma faixa
outputDefine os cálculos retornados por faixa
Exemplo

Collection products:

db.products.insertMany([
{ name: "Mouse", price: 50 },
{ name: "Teclado", price: 150 },
{ name: "Monitor", price: 900 },
{ name: "Notebook", price: 3500 }
])

Agregação com $bucket:

db.products.aggregate([
{
$bucket: {
groupBy: "$price",
boundaries: [0, 100, 500, 1000, 5000],
default: "fora da faixa",
output: {
total: { $sum: 1 },
produtos: { $push: "$name" },
precoMedio: { $avg: "$price" }
}
}
}
])

Resultado aproximado:

[
{
_id: 0,
total: 1,
produtos: ["Mouse"],
precoMedio: 50
},
{
_id: 100,
total: 1,
produtos: ["Teclado"],
precoMedio: 150
},
{
_id: 500,
total: 1,
produtos: ["Monitor"],
precoMedio: 900
},
{
_id: 1000,
total: 1,
produtos: ["Notebook"],
precoMedio: 3500
}
]
Como as faixas funcionam

Com:

boundaries: [0, 100, 500, 1000, 5000]

O MongoDB cria estas faixas:

_id do bucketFaixa
00 <= price < 100
100100 <= price < 500
500500 <= price < 1000
10001000 <= price < 5000

O valor inicial da faixa vira o _id do bucket.

Exemplo com $match antes
db.products.aggregate([
{
$match: {
active: true
}
},
{
$bucket: {
groupBy: "$price",
boundaries: [0, 100, 500, 1000, 5000],
default: "fora da faixa",
output: {
total: { $sum: 1 },
precoMedio: { $avg: "$price" }
}
}
}
])

Boa prática: use $match antes do $bucket para reduzir a quantidade de documentos processados.

C# Driver com BsonDocument
var pipeline = new[]
{
new BsonDocument("$match", new BsonDocument("active", true)),
new BsonDocument("$bucket", new BsonDocument
{
{ "groupBy", "$price" },
{ "boundaries", new BsonArray { 0, 100, 500, 1000, 5000 } },
{ "default", "fora da faixa" },
{
"output", new BsonDocument
{
{ "total", new BsonDocument("$sum", 1) },
{ "precoMedio", new BsonDocument("$avg", "$price") },
{ "produtos", new BsonDocument("$push", "$name") }
}
}
})
};

var result = await collection
.Aggregate<BsonDocument>(pipeline)
.ToListAsync();
Diferença entre $bucket e $group
EstágioUso principal
$groupAgrupa por valor exato
$bucketAgrupa por faixa de valores

Exemplo:

{ $group: { _id: "$category", total: { $sum: 1 } } }

Agrupa por categoria exata.

{
$bucket: {
groupBy: "$price",
boundaries: [0, 100, 500, 1000],
output: { total: { $sum: 1 } }
}
}

Agrupa por faixa de preço.

Resumo
PontoExplicação
$bucketAgrupa documentos em faixas
groupByCampo usado para classificar o documento
boundariesDefine os intervalos
defaultRecebe valores fora das faixas
outputCalcula totais, médias, listas, etc.
Uso comumHistogramas, filtros de preço, faixas de idade, relatórios

Observações Importantes

  • Cada estágio é executado sequencialmente
  • O output de um estágio é o input do próximo
  • A ordem dos stages impacta performance
  • $match deve ser usado no início sempre que possível
  • $project ajuda a reduzir payload

11) Administração e Monitoramento

11.1) Status do servidor

db.serverStatus()

11.2) Estatísticas do database atual

db.stats()

11.3) Estatísticas de uma coleção

db.<collection_name>.stats()

11.4) Espaço ocupado por uma coleção

db.<collection_name>.dataSize()

12) Usuários e Permissões

12.1) Criar usuário

db.createUser({
user: "<username>",
pwd: "<password>",
roles: [{ role: "<role>", db: "<database>" }]
})

12.2) Listar usuários do database

db.getUsers()

12.3) Remover usuário

db.dropUser("<username>")

12.4) Alterar senha do usuário

db.updateUser("<username>", { pwd: "<new_password>" })

13) Backup e Restauração (MongoDB Tools)

13.1) Exportar collection para JSON

mongoexport --db <database_name> --collection <collection_name> --out <file_name>.json

13.2) Importar JSON em uma collection

mongoimport --db <database_name> --collection <collection_name> --file <file_name>.json

14) Transações (quando aplicável)

14.1) Iniciar transação

session = db.getMongo().startSession()
session.startTransaction()

14.2) Commit da transação

session.commitTransaction()
session.endSession()

14.3) Abort da transação

session.abortTransaction()
session.endSession()

15) Replica Sets

15.1) Inicializar replica set

rs.initiate()

15.2) Ver status do replica set

rs.status()

15.3) Adicionar nó no replica set

rs.add("<hostname>:<port>")

15.4) Remover nó do replica set

rs.remove("<hostname>:<port>")

15.5) Forçar eleição de novo primário

rs.stepDown()

16) Sharding

16.1) Habilitar sharding em um database

sh.enableSharding("<database_name>")

16.2) Habilitar sharding em uma collection

sh.shardCollection(
"<database_name>.<collection_name>",
{ <shard_key>: 1 }
)

16.3) Ver status do sharding

sh.status()