Skip to main content

Mongoose (ODM) Basics

While MongoDB’s flexibility is powerful, it can also lead to problems. Without any structure, you might:
  • Insert documents with typos in field names (usernmae vs username)
  • Store different types in the same field (sometimes a string, sometimes a number)
  • Miss required fields entirely
  • Have no validation before data reaches the database
Mongoose solves these problems by adding a schema layer on top of MongoDB.

What is an ODM?

ODM stands for Object Data Modeling—it’s like an ORM (Object Relational Mapping) but for document databases. Mongoose maps JavaScript objects to MongoDB documents and provides:
FeatureBenefit
SchemasDefine structure for your documents
ValidationEnsure data meets requirements before saving
Type castingAutomatically convert types (string “42” → number 42)
MiddlewareRun code before/after save, update, delete
Query helpersClean, chainable API for queries
VirtualsComputed properties not stored in database

Why Use Mongoose?

Without Mongoose

// Direct MongoDB driver - no validation
await db.collection('users').insertOne({
  nmae: 'Alice',  // Typo - no warning!
  age: 'twenty-five'  // Wrong type - no warning!
});

With Mongoose

// Mongoose catches errors before they reach the database
const user = new User({
  nmae: 'Alice',  // Error: 'nmae' is not in schema
  age: 'twenty-five'  // Error: Cast to Number failed
});
await user.save();  // Throws ValidationError
Mongoose adds structure without removing flexibility. You can still use MongoDB’s schemaless features when needed with the Mixed type or strict mode disabled.

Installation

npm install mongoose

Connecting

const mongoose = require('mongoose');

mongoose.connect('mongodb://localhost:27017/myapp');

Defining a Schema

const Schema = mongoose.Schema;

const BlogPostSchema = new Schema({
  title: String,
  author: String,
  body: String,
  date: { type: Date, default: Date.now },
  hidden: Boolean,
  meta: {
    votes: Number,
    favs: Number
  }
});

Creating a Model

const BlogPost = mongoose.model('BlogPost', BlogPostSchema);

Creating a Document

const post = new BlogPost({
  title: 'Hello World',
  author: 'Alice',
  body: 'This is my first post.'
});

await post.save();

Querying

// Find all
const posts = await BlogPost.find();

// Find where author is Alice
const alicePosts = await BlogPost.find({ author: 'Alice' });

Validation

Mongoose has built-in validation.
const UserSchema = new Schema({
  username: {
    type: String,
    required: true,
    minlength: 5
  },
  age: {
    type: Number,
    min: 18,
    max: 65
  }
});

Summary

  • Mongoose provides structure to MongoDB documents in Node.js.
  • Schemas define the shape of documents.
  • Models provide an interface to the database.
  • Mongoose handles validation, casting, and business logic hooks.