MongoDB with Node.js — Complete Guide

Sanjeev SharmaSanjeev Sharma
3 min read

Advertisement

MongoDB is a document database perfect for flexible schemas and rapid development.

Setup

npm install mongodb
npm install --save-dev @types/mongodb

# Or use Mongoose (higher-level)
npm install mongoose

Native Driver

import { MongoClient } from "mongodb";

const client = new MongoClient("mongodb://localhost:27017");
await client.connect();

const db = client.db("myapp");
const users = db.collection("users");

// Insert
const result = await users.insertOne({
  name: "Alice",
  email: "alice@example.com",
});

// Find
const user = await users.findOne({ _id: result.insertedId });

// Update
await users.updateOne(
  { _id: result.insertedId },
  { $set: { name: "Alice Updated" } }
);

// Delete
await users.deleteOne({ _id: result.insertedId });

// Find many
const allUsers = await users.find({}).toArray();

Mongoose

import mongoose from "mongoose";

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

// Define schema
const userSchema = new mongoose.Schema({
  name: String,
  email: { type: String, unique: true },
  age: Number,
  createdAt: { type: Date, default: Date.now },
});

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

// Create
const user = await User.create({
  name: "Alice",
  email: "alice@example.com",
});

// Find
const found = await User.findById(user._id);

// Update
await User.updateOne({ _id: user._id }, { name: "Alice Updated" });

// Delete
await User.deleteOne({ _id: user._id });

Queries

// Filter
const adults = await User.find({ age: { $gte: 18 } });

// Regular expression
const names = await User.find({ name: /^A/ });

// Multiple conditions
const result = await User.find({
  $or: [
    { age: { $lt: 18 } },
    { email: { $regex: "@example.com" } },
  ],
});

// Projection
const emails = await User.find({}, { email: 1, _id: 0 });

// Sorting and pagination
const page = await User.find()
  .sort({ createdAt: -1 })
  .skip(10)
  .limit(10);

// Aggregation
const stats = await User.aggregate([
  { $group: { _id: "$email", count: { $sum: 1 } } },
  { $sort: { count: -1 } },
]);

Relationships

// Schema with references
const postSchema = new mongoose.Schema({
  title: String,
  content: String,
  author: {
    type: mongoose.Schema.Types.ObjectId,
    ref: "User",
  },
});

const Post = mongoose.model("Post", postSchema);

// Populate relationships
const postsWithAuthors = await Post.find().populate("author");

// Nested populate
const detailed = await Post.findById(postId).populate({
  path: "author",
  populate: { path: "profile" },
});

Indexes

userSchema.index({ email: 1 }); // Ascending
userSchema.index({ name: "text" }); // Text search
userSchema.index({ location: "2dsphere" }); // Geospatial

// Compound index
userSchema.index({ email: 1, createdAt: -1 });

Validation

const userSchema = new mongoose.Schema({
  name: { type: String, required: true, minlength: 3 },
  email: {
    type: String,
    required: true,
    match: /.+@.+\..+/,
  },
  age: { type: Number, min: 0, max: 150 },
  role: {
    type: String,
    enum: ["user", "admin"],
    default: "user",
  },
});

Hooks (Middleware)

userSchema.pre("save", async function () {
  if (!this.isModified("password")) return;
  this.password = await bcrypt.hash(this.password, 10);
});

userSchema.post("save", function (doc) {
  console.log("User saved:", doc._id);
});

Transactions

const session = await mongoose.startSession();
session.startTransaction();

try {
  const user = await User.create({ name: "Alice" }, { session });
  const post = await Post.create(
    { title: "First Post", authorId: user._id },
    { session }
  );
  await session.commitTransaction();
} catch (error) {
  await session.abortTransaction();
  throw error;
} finally {
  await session.endSession();
}

FAQ

Q: Should I use MongoDB or PostgreSQL? A: MongoDB for flexible schemas, rapid development. PostgreSQL for structured data, relationships, transactions.

Q: How do I backup MongoDB? A: Use mongodump for backup and mongorestore for restore.

Q: Is MongoDB good for relational data? A: It works but not optimal. PostgreSQL or other relational databases are better.


MongoDB is perfect for flexible schemas and document-oriented applications. Mongoose makes it easier to work with MongoDB in Node.js.

Advertisement

Sanjeev Sharma

Written by

Sanjeev Sharma

Full Stack Engineer · E-mopro