MongoDB, a NoSQL database, is a powerhouse when handling large-scale data. CampusX leverages MongoDB along with Mongoose, an ODM (Object Data Modeling) library, to structure and optimize database interactions. One of the core aspects of our implementation is MongoDB's aggregation pipelines, which allow us to efficiently fetch, transform, and compute data in a single query.
What is Mongoose?
Mongoose is a schema-based solution for MongoDB that provides a layer of abstraction, making it easier to interact with the database. It enables defining schemas, applying validation, and using middleware for handling complex operations.
Why Use Aggregation Pipelines?
MongoDB’s aggregation framework is a powerful feature that allows performing complex data transformations on the server side. Instead of fetching raw data and processing it in the application, aggregation pipelines execute these operations directly in the database, improving efficiency and performance.
Example: Fetching a Post with Mongoose Aggregation
One of the key functionalities in CampusX is retrieving posts along with associated details such as the author, comments, and follower count. Instead of making multiple queries, we optimize this using a MongoDB aggregation pipeline:
const post = await Post.aggregate([
{ $match: { _id: new mongoose.Types.ObjectId(postId) } },
{
$lookup: {
from: "users",
localField: "author",
foreignField: "_id",
as: "authorDetails",
},
},
{ $unwind: "$authorDetails" },
{
$lookup: {
from: "comments",
localField: "_id",
foreignField: "post",
as: "comments",
},
},
{
$lookup: {
from: "subscriptions",
localField: "author",
foreignField: "channel",
as: "followers",
},
},
{
$addFields: {
likeCount: { $size: "$likes" },
commentCount: { $size: "$comments" },
followerCount: { $size: "$followers" },
},
},
]);
Breakdown of the Pipeline Stages:
-
$match: Filters the post by its unique
_id
. -
$lookup (Users Collection): Joins the
users
collection to get the author details. - $unwind: Converts the array of author details into a single object.
- $lookup (Comments Collection): Fetches all comments associated with the post.
- $lookup (Subscriptions Collection): Retrieves followers of the author.
-
$addFields: Computes additional fields like
likeCount
,commentCount
, andfollowerCount
for quick reference.
This approach ensures we fetch all necessary data in one optimized query rather than executing multiple queries separately.
Schema Definition and Middleware in Mongoose
Our Post
schema defines relationships and pre-processing steps before deletion.
const postSchema = new mongoose.Schema(
{
author: {
type: mongoose.Schema.Types.ObjectId,
ref: "User",
required: true,
},
content: { type: String, required: true },
image: { type: String },
category: {
type: String,
enum: ["general", "exams", "placements", "competitions", "hackathons", "lost_found"],
default: "general",
},
likes: [{ type: mongoose.Schema.Types.ObjectId, ref: "User" }],
likesCount: { type: Number, default: 0 },
comments: [{ type: mongoose.Schema.Types.ObjectId, ref: "Comment" }],
},
{ timestamps: true }
);
Handling Deletions with Middleware
Mongoose allows us to trigger logic before deleting a post. The following middleware ensures associated comments and images are also removed when a post is deleted:
postSchema.pre("deleteOne", { document: true, query: false }, async function (next) {
console.log(`Deleting comments and image for post: ${this._id}`);
// Delete Comments
await Comment.deleteMany({ post: this._id });
// Delete Post Image if Exists
await deleteImage(this.image);
next();
});
postSchema.pre("deleteMany", { document: false, query: true }, async function (next) {
const posts = await this.model.find(this.getFilter());
for (const post of posts) {
console.log(`Deleting comments and image for post: ${post._id}`);
await Comment.deleteMany({ post: post._id });
await deleteImage(post.image);
}
next();
});
This ensures no orphaned records are left in the database after a post is deleted.
Why This Matters for CampusX?
- Performance Boost: The aggregation pipeline reduces multiple database calls, making queries significantly faster.
- Data Integrity: Middleware ensures that when a post is deleted, related comments and images are also removed.
- Schema Validation: Mongoose enforces structured data, reducing potential errors.
- Better Readability & Maintainability: Using Mongoose schemas and middleware makes the codebase easier to manage.
By combining MongoDB’s raw power with Mongoose’s flexibility, CampusX ensures an efficient, scalable, and maintainable database structure. 🚀
Top comments (0)