MongoDB Aggregation for Content Platforms: A Practical Guide
MongoDB's aggregation pipeline is a game-changer for filtering and transforming data in a concise, stage-wise manner. Think of it as an assembly line where each stage processes and refines your data before passing it to the next. In this article, I’ll guide you through its usage with a practical example from my full-stack YouTube-style project.
Here, we are working with two data models: User and Subscription. The User model contains all the information related to the user, such as full name, username, email, password, avatar, etc. The Subscription model has two fields, "subscriber" and "channel," both of which are of type User.
Note: A user is also a channel holder
Our goal? To fetch detailed information about a channel, including its subscriber count, subscriptions, and whether a logged-in user is subscribed to it.
Understanding the Stages
1. $match: Filtering by Username
When a user clicks a video, we extract the username from the request parameters. The $match
stage filters the User
collection to find the specific document matching this username.
{
$match: { username: username?.toLowerCase() }
}
2. $lookup: Joining with Subscription
The $lookup
stage allows us to perform a left outer join between the User
model and the Subscription
model.
To get the list of subscribers for the channel:
{
$lookup: {
from: "subscriptions",
localField: "_id",
foreignField: "channel",
as: "subscribers"
}
}
To fetch channels the user is subscribed to:
{
$lookup: {
from: "subscriptions",
localField: "_id",
foreignField: "subscriber",
as: "subscribedTo"
}
}
💡 Pro Tip: MongoDB converts model names to lowercase and pluralizes them in the database. For instance, Subscription
becomes subscriptions
.
3. $addFields: Calculating Counts and Subscription Status
The $addFields
stage lets us dynamically compute values and add them to the documents:
Subscriber Count : Use
$size
to get the number of users in thesubscribers
array.Subscribed Channels Count : Apply
$size
on thesubscribedTo
array.Is Subscribed : Use
$cond
to check if the logged-in user’s ID is in thesubscribers
array.
{
$addFields: {
subscribersCount: { $size: "$subscribers" },
channelSubscribedTo: { $size: "$subscribedTo" },
isSubscribed: {
$cond: {
if: { $in: [req.user?._id, "$subscribers.subscriber"] },
then: true,
else: false
}
}
}
}
4. $project: Sending Only Necessary Data
The $project
stage ensures we only send relevant fields to the frontend, reducing payload size.
{
$project: {
fullname: 1,
username: 1,
subscribersCount: 1,
channelSubscribedTo: 1,
isSubscribed: 1,
avatar: 1,
coverImage: 1
}
}
With just a few stages, we crafted an insightful response for the frontend, encompassing channel statistics and user-specific data. MongoDB’s aggregation pipeline is a powerful tool to simplify complex data manipulation tasks. By chaining stages like $match
, $lookup
, $addFields
, and $project
, you can transform your collections into precise, meaningful outputs tailored for your application.
Ready to power up your database skills? Experiment with other stages like $group
and $sort
to unlock more potential. 🚀
Dive into aggregation pipelines today!
Subscribe to my newsletter
Read articles from Yashraj Patil directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by