Mongoose Schemas & Models
Define document structure with a Mongoose Schema, compile it into a Model, and perform CRUD operations through it.
Defining a Schema
A Schema describes a document's shape — its fields, their types, and any constraints — as a plain JavaScript object passed to Mongoose's Schema constructor.
import mongoose from 'mongoose';
const userSchema = new mongoose.Schema({ name: { type: String, required: true }, email: { type: String, required: true, unique: true }, age: { type: Number, min: 0 }, isActive: { type: Boolean, default: true }, createdAt: { type: Date, default: Date.now },});Compiling a Model
A Model is compiled from a Schema, and is the actual interface your application code uses to create, query, update, and delete documents — Mongoose automatically maps a Model's name to a pluralized, lowercased collection name (User → users).
const User = mongoose.model('User', userSchema);Creating Documents
const user = await User.create({ name: 'Ada Lovelace', email: 'ada@example.com', age: 28 });console.log(user._id);Reading, Updating, and Deleting
Mongoose Models expose methods mirroring MongoDB's own operations, but returning richer, schema-aware document instances.
const users = await User.find({ isActive: true });const user = await User.findById('64f1a2b3c4d5e6f7a8b9c0d1');await User.updateOne({ email: 'ada@example.com' }, { $set: { age: 29 } });await User.deleteOne({ email: 'ada@example.com' });findById() is a Mongoose-specific shorthand for find({ _id: ... }) — one of several ergonomic additions layered on top of the raw driver's API.
Common Beginner Mistakes
Mongoose throws an "OverwriteModelError" if mongoose.model('User', ...) is called more than once — export and import a single shared model instance instead.
Every Mongoose query method returns a Promise — forgetting to await it means your code moves on before the actual database operation completes.
FAQs
Not necessarily — many teams use Mongoose schemas for everyday application-level validation and also add database-level JSON Schema validation as an additional safety net.
Yes — mongoose.connection.db gives you access to the raw MongoDB driver's database object for cases where Mongoose's abstraction doesn't fit.
Summary
A Schema defines document structure, and a Model compiled from it becomes your application's interface for CRUD operations. Next, you'll add validation and middleware hooks to a Mongoose schema.