1001Ferramentas
🍃 Geradores

Gerador de Mongoose model a partir de coleção

Gera um Schema + model Mongoose (JS) com campos básicos e timestamps — a partir do nome da coleção.

Schemas Mongoose: validação, population e middleware

O Mongoose é o ODM (Object Document Mapper) de facto para MongoDB em Node.js, criado por Valeri Karpov no time da LearnBoost em 2010 e hoje mantido pela MongoDB Inc. Não é um ORM SQL genérico — mira exclusivamente o MongoDB, adicionando uma camada de schema tipado, validação, middleware, population e API fluente de queries em cima do driver nativo. Quem escreve Node + MongoDB sem Mongoose normalmente reinventa metade desses recursos à mão.

Este gerador monta um mongoose.Schema + mongoose.model básicos; o guia abaixo cobre validators, hooks, population, sub-documents, índices, transações e como o Mongoose se compara ao driver bruto e ao suporte do Prisma a MongoDB.

Definindo um schema

const mongoose = require('mongoose');
const { Schema, Types: { ObjectId } } = mongoose;

const userSchema = new Schema({
  name: { type: String, required: true, trim: true },
  email: {
    type: String,
    unique: true,
    match: /^\S+@\S+$/,
    lowercase: true,
  },
  posts: [{ type: ObjectId, ref: 'Post' }],
  createdAt: { type: Date, default: Date.now },
}, { timestamps: true, strict: true });

const User = mongoose.model('User', userSchema);

Tipos embutidos: String, Number, Date, Buffer, Boolean, Mixed, ObjectId, Array, Decimal128, Map. Opções de coluna: required, default, unique, index, min, max, enum, match, trim, lowercase, mais função validate custom.

Population, virtuals, sub-documents

Population é o equivalente de um JOIN SQL no Mongoose — segue referências por ObjectId e injeta os documentos referenciados:

const user = await User
  .findById(id)
  .populate('posts')
  .populate({ path: 'comments', populate: { path: 'author' } });

Virtuals são propriedades computadas que nunca tocam o banco: userSchema.virtual('fullName').get(function () { return `${this.first} ${this.last}`; }). Sub-documents permitem aninhar schemas — úteis para value objects como endereços. Discriminators implementam herança: uma coleção Animal única pode guardar documentos Dog e Cat que compartilham um schema base e adicionam campos próprios.

Middleware, índices, transações

Middleware (hooks) rodam antes ou depois de eventos de ciclo de vida em save, find, update, remove e aggregation. Usos comuns: hash de senhas em pre('save'), emissão de eventos de auditoria em post('save'), filtros de soft delete via pre('find'). Índices ficam no nível do campo (index: true) ou compostos (schema.index({ email: 1, status: 1 })); defina autoIndex: false em produção e construa os índices fora do startup para não travar a inicialização. Transações exigem MongoDB 4.0+ e replica set — abra uma sessão com mongoose.startSession(), passe-a para as escritas; aborte e retente em erros transitórios.

Plugins, TypeScript, comparações

  • Plugins: mongoose-paginate-v2, mongoose-lean-virtuals, mongoose-autopopulate, mongoose-unique-validator são as extensões mais populares.
  • TypeScript: o Mongoose entrega os próprios tipos; para definições mais estritas e via decorator use Typegoose, que compila classes em schemas Mongoose.
  • vs driver bruto do MongoDB: o driver é mais leve e rápido, mas não tem validação nem enforcement de schema — ok para ETL ou serviços focados em aggregation.
  • vs Prisma com MongoDB: o Prisma ganhou suporte ao MongoDB, mas vários recursos (transações entre coleções, aggregations avançadas) estão menos maduros do que no mundo JS-only que o Prisma mira. O Mongoose segue sendo a ferramenta mais flexível para MongoDB hoje.
  • Aggregations: passe o pipeline direto com User.aggregate([{ $match }, { $group }, { $project }]) — o Mongoose repassa para o driver.
  • Strict mode: strict: true (default) descarta campos desconhecidos; strict: 'throw' joga erro em vez de silenciosamente largar os campos.

FAQ

Mongoose vale a pena com TypeScript? Sim. Os tipos nativos funcionam mas são verbosos; o Typegoose empacota schemas em classes decoradas, mantendo modelo e tipo TS sincronizados automaticamente.

populate é um JOIN de verdade? É o equivalente: o Mongoose roda uma segunda query para buscar os documentos referenciados e os costura no pai. O MongoDB não tem JOIN nativo — population emula um no driver.

O Mongoose valida antes de salvar? Sim — os validators do schema rodam em pre('save') e rejeitam o documento se qualquer campo falhar. Validators custom podem ser síncronos ou assíncronos. Em escritas em lote, a validação também roda a menos que você opte explicitamente por desligar.

Largar o Mongoose pelo driver bruto? Só se você não precisa de validação, hooks ou population. O driver é mais enxuto e rápido, mas você reconstrói várias redes de segurança à mão. A maioria do código de aplicação fica feliz com Mongoose; pipelines e bulk loaders podem rodar no driver puro.

Ferramentas Relacionadas