Aula 3 — Banco de Dados Orientado a Documentos
Fundamentos, modelagem, criação de banco, inserções, consultas ampliadas, atualizações, remoções,
embedding, referência, agregações e índices em MongoDB.
Objetivos da aula
- Compreender o modelo orientado a documentos
- Entender documentos, coleções, JSON e BSON
- Modelar dados com embedding e referência
- Criar banco, coleções e inserir documentos
- Executar consultas simples e avançadas
- Atualizar e remover documentos
- Conhecer agregação e índices
A proposta desta aula é unir conceito e prática, usando MongoDB para mostrar como a modelagem documental
influencia diretamente a forma de consultar e manipular os dados.
Mapa da aula
Fundamentos
- Documento
- Coleção
- JSON e BSON
- Schema flexível
Modelagem
- Agregados
- Embedding
- Referência
- Duplicação controlada
Prática
- Criação de banco
- Inserção
- Consultas
- Update, delete e índice
O que é um banco orientado a documentos?
É um banco de dados não relacional que organiza a informação em documentos,
agrupados em coleções.
- O documento representa uma unidade lógica de informação
- Pode conter campos simples, arrays e subdocumentos
- Nem todos os documentos precisam ter exatamente o mesmo formato
- O foco está no modo como a aplicação lê e grava os dados
Documento, coleção e tabela
Modelo relacional
- Tabelas
- Linhas
- Colunas
- Chaves estrangeiras
- Joins
Modelo documental
- Coleções
- Documentos
- Campos
- Subdocumentos
- Arrays
Um documento não é apenas uma linha com colunas. Ele pode armazenar estruturas completas dentro de si.
JSON e BSON
- JSON: formato textual, legível por humanos
- BSON: formato binário usado internamente em bancos como MongoDB
- O BSON suporta tipos adicionais, como datas e identificadores específicos
{
"nome": "Ana Souza",
"curso": "ADS",
"idade": 22,
"ativo": true,
"disciplinas": ["Banco de Dados", "MongoDB"]
}
Estrutura típica de um documento
{
"_id": "64f1...",
"nome": "Maria Souza",
"email": "maria@email.com",
"telefones": [
{ "tipo": "celular", "numero": "11999999999" },
{ "tipo": "trabalho", "numero": "1133333333" }
],
"endereco": {
"rua": "Rua A",
"cidade": "Campinas",
"uf": "SP"
},
"preferencias": {
"tema": "escuro",
"notificacoes": true
}
}
Modelagem orientada por padrão de acesso
- Quais dados a aplicação precisa exibir juntos?
- Quais consultas serão mais frequentes?
- Quais campos mudam com frequência?
- Quais informações podem ser duplicadas sem grande risco?
No modelo documental, a modelagem costuma ser guiada pelo padrão de leitura e pelo contexto de uso da aplicação.
Agregado e duplicação controlada
Um agregado é um conjunto de dados tratado como unidade lógica.
- Pedido com itens e endereço
- Usuário com contatos e preferências
- Produto com atributos e variações
Em muitos casos, repetir alguns dados é aceitável para facilitar a leitura e preservar contexto histórico.
Embedding x referência
Embedding
- Dados fortemente relacionados
- Lidos juntos com frequência
- Atualizados em conjunto
- Favorece leitura
Referência
- Dado compartilhado em muitos contextos
- Atualização frequente e centralizada
- Evita repetição excessiva
- Favorece reuso
Exemplo: embedding
db.clientes.insertOne({
nome: "Paula Mendes",
telefones: [
{ tipo: "celular", numero: "11999999999" }
],
endereco: {
cidade: "Campinas",
uf: "SP"
}
})
Exemplo: referência
db.cursos.insertOne({
_id: 10,
nome: "Análise e Desenvolvimento de Sistemas"
})
db.alunos.insertOne({
ra: "R010",
nome: "Felipe Costa",
curso_id: 10
})
Embedding favorece leitura em um único documento. Referência favorece reuso e atualização centralizada.
Primeiros comandos no MongoDB
use escola
db.createCollection("alunos")
show collections
Em muitos casos, a coleção também pode ser criada implicitamente na primeira inserção.
Inserção de um documento
db.alunos.insertOne({
ra: "R001",
nome: "Ana Souza",
curso: "ADS",
idade: 22
})
Inserção com subdocumentos e arrays
db.alunos.insertOne({
ra: "R002",
nome: "Carlos Lima",
curso: "CC",
idade: 24,
endereco: {
cidade: "Campinas",
uf: "SP"
},
disciplinas: ["MongoDB", "Python", "Estatística"]
})
Inserção de vários documentos
db.alunos.insertMany([
{
ra: "R003",
nome: "Marina Alves",
curso: "SI",
idade: 21,
endereco: { cidade: "Jundiaí", uf: "SP" },
disciplinas: ["Banco de Dados", "Java"]
},
{
ra: "R004",
nome: "João Pedro",
curso: "ADS",
idade: 23,
endereco: { cidade: "Itatiba", uf: "SP" },
disciplinas: ["MongoDB", "Redes"]
}
])
Exercício inicial
Criação e inserção
Crie um banco e uma coleção chamada produtos. Depois, insira 3 documentos com:
- nome
- categoria
- preco
- estoque
Consulta básica
db.alunos.find()
db.alunos.find().pretty()
A primeira consulta mostra a coleção completa. O método pretty() ajuda na visualização.
Consulta por igualdade
db.alunos.find({ curso: "ADS" })
db.alunos.find({ idade: 22 })
Consulta com múltiplos campos
db.alunos.find({
curso: "ADS",
idade: 22
})
Quando vários campos aparecem no mesmo objeto, a lógica aplicada é um AND.
Operadores de comparação
db.alunos.find({ idade: { $gt: 21 } })
db.alunos.find({ idade: { $gte: 21 } })
db.alunos.find({ idade: { $lt: 23 } })
db.alunos.find({ idade: { $lte: 23 } })
db.alunos.find({ curso: { $ne: "ADS" } })
Intervalo e operador IN
db.alunos.find({
idade: { $gte: 20, $lte: 23 }
})
db.alunos.find({
curso: { $in: ["ADS", "CC"] }
})
db.alunos.find({
curso: { $nin: ["ADS", "CC"] }
})
Operadores lógicos
db.alunos.find({
$and: [
{ curso: "ADS" },
{ idade: { $gt: 20 } }
]
})
db.alunos.find({
$or: [
{ curso: "ADS" },
{ curso: "SI" }
]
})
Projeção
db.alunos.find(
{ curso: "ADS" },
{ nome: 1, curso: 1, _id: 0 }
)
db.alunos.find(
{},
{ nome: 1, idade: 1, _id: 0 }
)
Ordenação e limite
db.alunos.find().sort({ nome: 1 })
db.alunos.find().sort({ idade: -1 })
db.alunos.find().limit(3)
db.alunos.find().sort({ idade: -1 }).limit(2)
Consultas em campos aninhados
db.alunos.find({
"endereco.cidade": "Campinas"
})
db.alunos.find({
"endereco.uf": "SP"
})
Consultas em arrays
db.alunos.find({
disciplinas: "MongoDB"
})
db.alunos.find({
disciplinas: { $in: ["MongoDB", "Python"] }
})
db.alunos.find({
disciplinas: { $size: 2 }
})
Arrays de objetos e $elemMatch
db.clientes.insertOne({
nome: "Paula Mendes",
contatos: [
{ tipo: "celular", valor: "11999999999" },
{ tipo: "email", valor: "paula@email.com" }
]
})
db.clientes.find({
"contatos.tipo": "email"
})
db.clientes.find({
contatos: {
$elemMatch: {
tipo: "email",
valor: "paula@email.com"
}
}
})
Existência, contagem e distinct
db.alunos.find({
telefone: { $exists: true }
})
db.alunos.countDocuments()
db.alunos.countDocuments({ curso: "ADS" })
db.alunos.distinct("curso")
Consulta completa
db.alunos.find(
{
curso: "ADS",
idade: { $gte: 20 },
"endereco.uf": "SP",
disciplinas: "MongoDB"
},
{
nome: 1,
curso: 1,
disciplinas: 1,
_id: 0
}
).sort({ nome: 1 }).limit(5)
Atualização com updateOne
db.alunos.updateOne(
{ ra: "R001" },
{ $set: { idade: 23 } }
)
Atualização com updateMany
db.alunos.updateMany(
{ curso: "ADS" },
{ $set: { turno: "Noturno" } }
)
Operadores de atualização
db.produtos.updateOne(
{ nome: "Mouse" },
{ $inc: { estoque: -1 } }
)
db.produtos.updateOne(
{ nome: "Notebook" },
{ $unset: { observacao: "" } }
)
db.alunos.updateOne(
{ ra: "R001" },
{ $push: { disciplinas: "Banco de Dados Não Relacionais" } }
)
db.alunos.updateOne(
{ ra: "R001" },
{ $pull: { disciplinas: "Lógica" } }
)
Remoção
db.alunos.deleteOne({ ra: "R004" })
db.alunos.deleteMany({ curso: "SI" })
Remoções devem sempre ser feitas com filtros bem definidos.
Exercícios de consulta
- Buscar todos os alunos do curso ADS
- Buscar alunos com idade maior que 21
- Buscar alunos de Campinas
- Buscar alunos que cursam MongoDB
- Mostrar apenas nome e curso
- Ordenar por idade decrescente
- Contar quantos alunos há por curso
- Descobrir os cursos distintos da coleção
Exercícios de modelagem
- Modelar um cliente com telefones e endereço
- Modelar um pedido com itens, pagamento e status
O que é agregação?
A agregação permite transformar e resumir dados em etapas, por meio de um pipeline.
- Filtrar
- Projetar
- Agrupar
- Ordenar
- Limitar
Pipeline básico
db.produtos.aggregate([
{ $match: { categoria: "Periféricos" } },
{ $project: { nome: 1, preco: 1, _id: 0 } },
{ $sort: { preco: -1 } }
])
Agrupando dados
db.produtos.aggregate([
{
$group: {
_id: "$categoria",
totalProdutos: { $sum: 1 },
mediaPreco: { $avg: "$preco" }
}
}
])
Por que índices importam?
- Índice melhora leitura e busca
- Índice pode acelerar ordenação
- Índice também tem custo de manutenção na escrita
Índice simples e composto
db.alunos.createIndex({ ra: 1 })
db.produtos.createIndex({ categoria: 1 })
db.pedidos.createIndex({ status: 1, data: -1 })
Resumo da aula
- O modelo documental organiza dados em documentos e coleções
- JSON e BSON são bases importantes para esse paradigma
- Embedding e referência são decisões centrais de modelagem
- MongoDB permite criação, inserção, consulta, atualização e remoção de documentos
- Consultas podem envolver campos simples, arrays e subdocumentos
- Agregação e índices ampliam a capacidade analítica e o desempenho
Perguntas para revisão
- O que diferencia um documento de uma linha de tabela?
- Quando vale a pena usar embedding?
- Quando a referência é mais adequada?
- Como o padrão de consulta influencia a modelagem?
- Quais operadores de consulta são mais úteis no dia a dia?
- Por que índices não devem ser criados sem critério?