Advanced

Mongoose ODM

Use Mongoose to model your MongoDB data with schemas, validation, and middleware.

What is Mongoose?

Mongoose is an Object Data Modeling (ODM) library for MongoDB and Node.js. It provides:

  • Schema definition: Define the shape and validation of documents
  • Type casting: Convert values to the correct types
  • Validation: Built-in and custom validators
  • Middleware (hooks): Pre/post hooks for operations
  • Query building: Chainable query API

Schema and Model

  1. Define a Schema — the shape and rules for documents
  2. Create a Model from the schema — the interface for CRUD operations

Example

javascript
const mongoose = require('mongoose');

// Connect to MongoDB
await mongoose.connect('mongodb://localhost:27017/myapp');

// Define schema
const userSchema = new mongoose.Schema({
  name: {
    type: String,
    required: [true, 'Name is required'],
    trim: true,
    minlength: 2,
    maxlength: 50,
  },
  email: {
    type: String,
    required: true,
    unique: true,
    lowercase: true,
    match: [/^\S+@\S+\.\S+$/, 'Invalid email'],
  },
  password: {
    type: String,
    required: true,
    minlength: 8,
    select: false,  // excluded from queries by default
  },
  role: {
    type: String,
    enum: ['user', 'admin', 'moderator'],
    default: 'user',
  },
  age: { type: Number, min: 0, max: 150 },
  tags: [String],
  address: {
    city: String,
    country: String,
  },
  createdAt: { type: Date, default: Date.now },
}, {
  timestamps: true,  // auto-adds createdAt and updatedAt
});

// Virtual field (not stored in DB)
userSchema.virtual('displayName').get(function() {
  return `${this.name} (${this.role})`;
});

// Pre-save middleware (hash password before saving)
userSchema.pre('save', async function(next) {
  if (this.isModified('password')) {
    this.password = await bcrypt.hash(this.password, 12);
  }
  next();
});

// Instance method
userSchema.methods.comparePassword = async function(candidate) {
  return bcrypt.compare(candidate, this.password);
};

// Static method
userSchema.statics.findByEmail = function(email) {
  return this.findOne({ email: email.toLowerCase() });
};

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

// Usage
const user = await User.create({ name: 'Alice', email: 'alice@example.com', password: 'secure123' });
const found = await User.findByEmail('alice@example.com');
await User.findByIdAndUpdate(user._id, { role: 'admin' }, { new: true });

Want to run this code interactively?

Try in Compiler