Introduction
A Many-to-Many Relationship in MongoDB occurs when multiple documents in one collection can be related to multiple documents in another collection. For example, one student can enroll in many courses, and one course can have many students. MongoDB does not provide traditional SQL-style joins by default, so many-to-many relationships are commonly handled using arrays, references, or $lookup. In this chapter, you will practice creating and querying many-to-many relationships. MongoDB Many-to-Many Relationships Practice questions with solutions to help you understand the concepts.
Q1. Create Students and Courses Collections
Problem Statement
Create a students collection and a courses collection to represent students and courses.
MongoDB Command / Query
db.students.insertMany([
{
studentId: 101,
name: "Rahul",
courses: [1, 2]
},
{
studentId: 102,
name: "Priya",
courses: [1, 3]
},
{
studentId: 103,
name: "Amit",
courses: [2, 3]
}
])
db.courses.insertMany([
{
courseId: 1,
courseName: "MongoDB"
},
{
courseId: 2,
courseName: "Python"
},
{
courseId: 3,
courseName: "JavaScript"
}
])
Expected Output
The students collection contains:
Rahul → MongoDB, Python
Priya → MongoDB, JavaScript
Amit → Python, JavaScript
Explanation
The courses array stores references to courses using their courseId. A student can have multiple courses, while the same course can belong to multiple students.
Q2. Find Students Enrolled in a Particular Course
Problem Statement
Find all students who are enrolled in the course with courseId: 1.
MongoDB Command / Query
db.students.find({
courses: 1
})
Expected Output
Rahul
Priya
Explanation
MongoDB automatically matches the value 1 against elements inside the courses array.
Q3. Find Students Enrolled in Multiple Courses
Problem Statement
Find students who are enrolled in both MongoDB and Python.
MongoDB Command / Query
db.students.find({
courses: { $all: [1, 2] }
})
Expected Output
Rahul
Explanation
$all checks whether an array contains all specified values.
Rahul has:
courses: [1, 2]
so he matches the query.
Q4. Add Another Course to a Student
Problem Statement
Rahul wants to enroll in JavaScript. Add course 3 to his courses.
MongoDB Command / Query
db.students.updateOne(
{ studentId: 101 },
{ $addToSet: { courses: 3 } }
)
Expected Output
Rahul’s document becomes:
{
studentId: 101,
name: "Rahul",
courses: [1, 2, 3]
}
Explanation
$addToSet adds a value to an array only if it doesn’t already exist. This is useful for avoiding duplicate course references.
Q5. Remove a Course from a Student
Problem Statement
Rahul decides to stop studying Python. Remove course 2 from his courses.
MongoDB Command / Query
db.students.updateOne(
{ studentId: 101 },
{ $pull: { courses: 2 } }
)
Expected Output
{
studentId: 101,
name: "Rahul",
courses: [1, 3]
}
Explanation
$pull removes matching values from an array.
Q6. Find Students Taking at Least Two Courses
Problem Statement
Find students who are enrolled in two or more courses.
MongoDB Command / Query
db.students.find({
$expr: {
$gte: [
{ $size: "$courses" },
2
]
}
})
Expected Output
Rahul
Priya
Amit
Explanation
$size counts the number of elements in the courses array. $expr allows us to compare that count with 2.
Q7. Use $lookup to Get Course Details
Problem Statement
Display each student’s course IDs along with the actual course documents.
MongoDB Command / Query
db.students.aggregate([
{
$lookup: {
from: "courses",
localField: "courses",
foreignField: "courseId",
as: "courseDetails"
}
}
])
Expected Output
A student document can look like:
{
studentId: 101,
name: "Rahul",
courses: [1, 2],
courseDetails: [
{
courseId: 1,
courseName: "MongoDB"
},
{
courseId: 2,
courseName: "Python"
}
]
}
Explanation
$lookup connects the students collection with the courses collection.
Here:
students.courses
↓
courses.courseId
This is one of the most important techniques for working with referenced many-to-many relationships.
Q8. Find All Students for the MongoDB Course
Problem Statement
Find all students who are enrolled in the course named "MongoDB".
MongoDB Command / Query
db.students.aggregate([
{
$lookup: {
from: "courses",
localField: "courses",
foreignField: "courseId",
as: "courseDetails"
}
},
{
$match: {
"courseDetails.courseName": "MongoDB"
}
},
{
$project: {
_id: 0,
studentId: 1,
name: 1
}
}
])
Expected Output
[
{
studentId: 101,
name: "Rahul"
},
{
studentId: 102,
name: "Priya"
}
]
Explanation
First, $lookup finds the course information. Then $match filters students whose course details contain "MongoDB".
Q9. Find Courses Taken by Rahul
Problem Statement
Find Rahul’s courses and display their course names instead of only their IDs.
MongoDB Command / Query
db.students.aggregate([
{
$match: {
studentId: 101
}
},
{
$lookup: {
from: "courses",
localField: "courses",
foreignField: "courseId",
as: "courseDetails"
}
},
{
$project: {
_id: 0,
name: 1,
"courseDetails.courseName": 1
}
}
])
Expected Output
{
name: "Rahul",
courseDetails: [
{
courseName: "MongoDB"
},
{
courseName: "Python"
}
]
}
Explanation
The aggregation pipeline first finds Rahul and then uses $lookup to retrieve the corresponding course documents.
Q10. Count Students Enrolled in Each Course
Problem Statement
Find how many students are enrolled in each course.
MongoDB Command / Query
db.students.aggregate([
{
$unwind: "$courses"
},
{
$group: {
_id: "$courses",
studentCount: { $sum: 1 }
}
},
{
$lookup: {
from: "courses",
localField: "_id",
foreignField: "courseId",
as: "course"
}
},
{
$project: {
_id: 0,
courseName: { $arrayElemAt: ["$course.courseName", 0] },
studentCount: 1
}
}
])
Expected Output
MongoDB → 2 students
Python → 2 students
JavaScript → 2 students
Explanation
$unwind separates each course ID into an individual document. $group counts the students for each course. $lookup then adds the course name.
Key Takeaways
- A Many-to-Many Relationship means multiple documents can be associated with multiple documents.
- MongoDB commonly represents relationships using arrays and references.
- A student’s
coursesarray can contain multiple course IDs. - The same course ID can appear in many student documents.
$allchecks whether an array contains multiple specified values.$addToSetadds a value without creating duplicates.$pullremoves a value from an array.$lookupcan connect related collections.$unwindis useful when working with arrays during aggregation.$groupcan be used to count related documents.
FAQs
1. What is a Many-to-Many Relationship in MongoDB?
A Many-to-Many Relationship occurs when multiple documents from one collection can be related to multiple documents from another collection. For example, students can enroll in multiple courses, and each course can have multiple students.
2. How can Many-to-Many Relationships be stored in MongoDB?
They can commonly be stored using arrays containing references to related documents. For example:
{
studentId: 101,
courses: [1, 2, 3]
}
3. Can MongoDB perform joins between collections?
Yes. MongoDB provides the $lookup aggregation stage to combine related documents from different collections.
4. What is the difference between $addToSet and $push?
$addToSet adds a value only if it doesn’t already exist in the array, while $push adds the value even if it creates a duplicate.
5. How do you remove a reference from an array in MongoDB?
Use $pull. For example:
db.students.updateOne(
{ studentId: 101 },
{ $pull: { courses: 2 } }
)
6. Why are references useful in Many-to-Many Relationships?
References avoid storing complete copies of related documents. Instead, documents store IDs that point to related documents.
7. When should $lookup be used in a Many-to-Many Relationship?
Use $lookup when you need to retrieve related information from another collection, such as getting complete course details for the course IDs stored inside a student’s document.
Written by Shubhranshu Shekhar, who has trained 20000+ students in coding.
