Pular para o conteúdo
Cursos

DevClub

LógicaFront-endBack-endMobile

IA Club

IA na prática
Estudar programaçãoEstudar IA

Aula 2 de 6

Modele documentos MongoDB por acesso aos dados

Aprenda a escolher entre dados incorporados e referências observando leitura, atualização, crescimento e consistência de cada relação.

48 minutos · leitura + prática · nível iniciante

Ao terminar esta aula, você vai conseguir

  • Modelar documentos a partir das consultas da aplicação
  • Comparar incorporação e referência com critérios concretos
  • Reconhecer arrays que podem crescer sem limite
Três documentos independentes guardam nome e estado ativo.

Modelar no MongoDB é decidir quais dados vivem juntos em cada documento. A boa decisão começa pelas operações que a aplicação executará: o que é lido junto, o que muda junto e o que pode crescer. Nesta aula, você vai comparar dados incorporados com referências e justificar uma escolha.

Imagine preparar uma mochila para uma aula. Caderno e caneta que sempre viajam juntos ficam dentro dela; um livro raro compartilhado pela turma permanece na biblioteca e você leva apenas o código para encontrá-lo. Incorporar é guardar os dados relacionados no mesmo documento. Referenciar é guardar um identificador que aponta para outro documento. O limite da analogia é que o MongoDB não segue automaticamente toda referência: normalmente a aplicação ou uma agregação faz a leitura adicional.

Comece pelas perguntas, não pelas entidades

Suponha que a tela de curso sempre mostre título e instrutor. Uma versão incorporada poderia ser:

json
{
  "titulo": "HTML do zero",
  "instrutor": {
    "nome": "Ana",
    "cidade": "Recife"
  }
}

Uma leitura encontra tudo em uma unidade. Atualizações no mesmo documento são atômicas: outras operações não observam metade dessa alteração. Porém, se Ana mudar de cidade e sua ficha estiver copiada em mil cursos, todas as cópias precisarão ser revisadas.

Com referência, os documentos ficariam separados:

javascript
// cursos
{ titulo: 'HTML do zero', instrutorId: ObjectId('...') }

// instrutores
{ _id: ObjectId('...'), nome: 'Ana', cidade: 'Recife' }

A cidade tem uma fonte principal, mas a tela pode precisar de outra consulta ou de $lookup. Não escolha referência apenas para imitar tabelas relacionais. Escolha quando a entidade é consultada separadamente, compartilhada por muitos documentos ou atualizada com frequência.

Observe cardinalidade e crescimento

Cardinalidade descreve quantos itens se relacionam. Um curso pode ter poucas informações de contato do instrutor; esse conjunto é limitado. Já um curso pode receber comentários durante anos. Incorporar todos em um array cria um documento que cresce sem controle, disputa atualizações e se aproxima do limite de tamanho do BSON.

Este modelo reproduz o problema:

javascript
db.cursos.updateOne(
  { _id: cursoId },
  { $push: { comentarios: novoComentario } }
)

O comando funciona no início, por isso o erro passa despercebido. O defeito é de crescimento: cada comentário aumenta o mesmo documento. Uma coleção separada de comentários, com cursoId, permite paginar e indexar esse histórico.

Aceite duplicação somente com uma regra

Duplicar um pequeno resumo pode economizar leituras, mas você precisa decidir se o valor é uma fotografia histórica ou uma cópia sincronizada. O endereço do pedido deve permanecer como estava na compra; já o nome público do instrutor pode exigir atualização. Sem essa definição, duas telas mostram versões diferentes e ninguém sabe qual está correta.

O modelo também precisa dizer quais campos são obrigatórios e quais tipos são aceitos. Essa regra pode existir na aplicação e na validação de schema da coleção. Se instrutor.nome for necessário para a tela, um documento que traz apenas instrutor: {} deve falhar na entrada, não causar um título vazio meses depois. Validação não decide entre incorporação e referência, mas protege a forma escolhida.

Documente ainda a migração. Ao acrescentar um campo obrigatório, documentos antigos não ganham valor sozinhos. Planeje um padrão temporário, atualize os registros existentes e só depois aperte a validação. Essa sequência evita que uma boa regra nova interrompa leituras legítimas do acervo anterior.

O laboratório usa caminho com ponto para ler instrutor.nome. Ele é um simulador didático sobre dados JSON, não um MongoDB real: não persiste, não faz $lookup, não impõe validação e oferece apenas os filtros listados no curso. Execute {"instrutor.nome":"Ana"} e espere dois cursos. Troque por "Caio" e espere um.

Sua missão é desenhar um pedido com cliente, endereço e itens. Para cada parte, escreva “incorporar” ou “referenciar” e uma consulta que sustenta a decisão. Depois identifique o que pode crescer. Na próxima aula, esse modelo receberá operações de criação, leitura, atualização e remoção.

Laboratório ao vivo

Consulte um campo incorporado

Filtre pelo nome do instrutor usando caminho com ponto. O laboratório simula filtros sobre JSON; não executa modelagem nem consultas em MongoDB real.

Pronto para testar

Resultado

Pare e pense

Quando incorporar dados relacionados costuma ser uma boa escolha?

Escolha uma resposta
Missão da aula

Faça sem copiar

Modele um pedido com endereço congelado no momento da compra e produtos por referência. Escreva duas consultas que justificam cada decisão.

Fontes para consultar

Terminou a missão?

Marque apenas quando você conseguir explicar o conceito e concluir o desafio. O progresso fica salvo somente neste navegador.

Próxima: CRUD no MongoDB: criar, ler, atualizar e remover →