DEV Community

Alex Spinov
Alex Spinov

Posted on

Mongoose Has a Free API — Here's How to Model and Query MongoDB in Node.js

Mongoose is the most popular MongoDB ODM for Node.js. It provides schema validation, middleware hooks, population, and a powerful query builder.

Installation

npm install mongoose
Enter fullscreen mode Exit fullscreen mode

Connection

import mongoose from "mongoose";

await mongoose.connect("mongodb://localhost:27017/mydb");
console.log("Connected to MongoDB");
Enter fullscreen mode Exit fullscreen mode

Schema and Model

import { Schema, model, Types } from "mongoose";

const userSchema = new Schema({
  email: { type: String, required: true, unique: true, lowercase: true },
  name: { type: String, required: true, trim: true },
  role: { type: String, enum: ["user", "admin"], default: "user" },
  posts: [{ type: Types.ObjectId, ref: "Post" }],
  createdAt: { type: Date, default: Date.now }
});

// Instance methods
userSchema.methods.fullName = function() {
  return `${this.name} (${this.role})`;
};

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

// Middleware
userSchema.pre("save", function(next) {
  console.log(`Saving user: ${this.email}`);
  next();
});

const User = model("User", userSchema);
Enter fullscreen mode Exit fullscreen mode

CRUD Operations

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

// Find with query builder
const admins = await User.find({ role: "admin" })
  .sort({ createdAt: -1 })
  .limit(10)
  .select("name email")
  .lean();

// Update
await User.findByIdAndUpdate(user._id, { name: "Updated" }, { new: true });

// Delete
await User.deleteMany({ role: "inactive" });
Enter fullscreen mode Exit fullscreen mode

Population (Joins)

const userWithPosts = await User.findById(userId)
  .populate({
    path: "posts",
    select: "title createdAt",
    options: { sort: { createdAt: -1 }, limit: 5 }
  });
Enter fullscreen mode Exit fullscreen mode

Aggregation Pipeline

const stats = await User.aggregate([
  { $group: { _id: "$role", count: { $sum: 1 }, latestSignup: { $max: "$createdAt" } } },
  { $sort: { count: -1 } }
]);
console.log(stats); // [{ _id: "user", count: 150, ... }, { _id: "admin", count: 5, ... }]
Enter fullscreen mode Exit fullscreen mode

Virtuals

userSchema.virtual("postCount", {
  ref: "Post",
  localField: "_id",
  foreignField: "author",
  count: true
});

const user = await User.findById(id).populate("postCount");
console.log(user.postCount); // 42
Enter fullscreen mode Exit fullscreen mode

Need to extract or automate web content at scale? Check out my web scraping tools on Apify — no coding required. Or email me at spinov001@gmail.com for custom solutions.

Top comments (0)