Paramclasses Academy - Blog

Tutorials Details

←
Post 18 of 35
→

How to Design One-to-One, One-to-Many and Many-to-Many Relationships in MongoDB

How to Design One-to-One, One-to-Many and Many-to-Many Relationships in MongoDB

November 5, 2026

How to Design One-to-One, One-to-Many and Many-to-Many Relationships in MongoDB

Introduction

When building a database application, data is often connected. For example, one student may have one profile, one department may have multiple employees, and one student may enroll in multiple courses.

In relational databases such as MySQL, these connections are commonly designed using tables and foreign keys. MongoDB is a document-oriented NoSQL database, so relationships are generally represented using embedded documents or references.

MongoDB supports flexible data modeling. You can store related information inside the same document or keep it in separate collections and connect the documents using their IDs.

In this tutorial, you will learn:

  • What relationships mean in MongoDB.

  • What is a One-to-One relationship?

  • What is a One-to-Many relationship?

  • What is a Many-to-Many relationship?

  • How to use embedded documents.

  • How to use references between collections.

  • How to retrieve related information using $lookup.

Let's understand each relationship with practical examples using MongoDB Shell (mongosh).

1. What Are Relationships in MongoDB?

A relationship describes how one document is connected to another document.

For example, consider a student management system:

  • One student has one profile.

  • One department has many students.

  • Many students can enroll in many courses.

These are examples of One-to-One, One-to-Many and Many-to-Many relationships.

MongoDB provides two common ways to represent related data:

1. Embedded Documents

Related information is stored inside the same document.

2. References

Related information is stored in separate collections, and documents are connected using their IDs.

The right approach depends on how your application reads, updates and manages data.

2. One-to-One Relationship in MongoDB

A One-to-One relationship means one document is associated with one other document.

Real-World Example

Consider a student and their student profile.

Each student has one profile, and each profile belongs to one student.

Method 1: One-to-One Using Embedded Documents

You can store profile information directly inside the student document.

First, create a database:

use schoolDB

Insert a student with embedded profile information:

db.students.insertOne({
    name: "Rahul Sharma",
    age: 22,
    email: "rahul@example.com",
    profile: {
        gender: "Male",
        city: "Raipur",
        phone: "9876543210"
    }
})

To retrieve the student:

db.students.find()

To find a student using the profile city:

db.students.find({
    "profile.city": "Raipur"
})

Here, the profile object is embedded inside the student document.

Advantages:

  • Related data can be retrieved in one query.

  • The document structure is easy to understand.

  • No separate collection is required for the profile.

Method 2: One-to-One Using References

You can also store student and profile information in separate collections.

Insert a student:

db.students.insertOne({
    _id: 101,
    name: "Rahul Sharma",
    age: 22
})

Insert the student's profile in another collection:

db.profiles.insertOne({
    studentId: 101,
    gender: "Male",
    city: "Raipur",
    phone: "9876543210"
})

Here, studentId connects the profile document to the student document.

To retrieve the related information, use $lookup:

db.students.aggregate([
    {
        $lookup: {
            from: "profiles",
            localField: "_id",
            foreignField: "studentId",
            as: "studentProfile"
        }
    }
])

The $lookup stage combines matching documents from another collection in the aggregation result.

When to use references:

  • When profile information is managed independently.

  • When the related document may be accessed separately.

  • When embedding would make the main document unnecessarily large.

3. One-to-Many Relationship in MongoDB

A One-to-Many relationship means one document is associated with multiple related documents.

Real-World Example

Consider a department and its employees.

One department can have multiple employees, but each employee belongs to one department.

Method 1: One-to-Many Using Embedded Documents

You can store multiple employee records inside one department document using an array.

Insert a department:

db.departments.insertOne({
    departmentName: "IT",
    location: "Raipur",
    employees: [
        {
            name: "Rahul",
            designation: "Developer"
        },
        {
            name: "Amit",
            designation: "Designer"
        },
        {
            name: "Priya",
            designation: "Tester"
        }
    ]
})

To retrieve the department:

db.departments.find()

To find the IT department:

db.departments.find({
    departmentName: "IT"
})

Here, multiple employee documents are stored inside the employees array.

Advantages:

  • All department and employee information can be retrieved together.

  • The structure is simple for small, bounded groups of related data.

  • Fewer separate queries may be needed.

Method 2: One-to-Many Using References

If a department has many employees or employee records need to be managed independently, you can use separate collections.

Insert a department:

db.departments.insertOne({
    _id: 1,
    departmentName: "IT",
    location: "Raipur"
})

Insert employees in a separate collection:

db.employees.insertMany([
    {
        name: "Rahul",
        designation: "Developer",
        departmentId: 1
    },
    {
        name: "Amit",
        designation: "Designer",
        departmentId: 1
    },
    {
        name: "Priya",
        designation: "Tester",
        departmentId: 1
    }
])

Here, each employee document contains a departmentId that references the department.

To find all employees belonging to the IT department:

db.employees.find({
    departmentId: 1
})

To retrieve departments along with their employees:

db.departments.aggregate([
    {
        $lookup: {
            from: "employees",
            localField: "_id",
            foreignField: "departmentId",
            as: "employees"
        }
    }
])

When to use references:

  • When the number of related documents can grow significantly.

  • When related records need to be updated independently.

  • When you frequently query employees separately from departments.

4. Many-to-Many Relationship in MongoDB

A Many-to-Many relationship means multiple documents in one collection can be associated with multiple documents in another collection.

Real-World Example

Consider students and courses:

  • One student can enroll in multiple courses.

  • One course can have multiple students.

This is a Many-to-Many relationship.

Method 1: Many-to-Many Using References and Arrays

You can store course IDs in each student document and student IDs in each course document.

Insert students:

db.students.insertMany([
    {
        _id: 1,
        name: "Rahul",
        courseIds: [101, 102]
    },
    {
        _id: 2,
        name: "Priya",
        courseIds: [101, 103]
    }
])

Insert courses:

db.courses.insertMany([
    {
        _id: 101,
        courseName: "MongoDB"
    },
    {
        _id: 102,
        courseName: "JavaScript"
    },
    {
        _id: 103,
        courseName: "Python"
    }
])

To find the courses selected by Rahul:

db.students.aggregate([
    {
        $match: {
            _id: 1
        }
    },
    {
        $lookup: {
            from: "courses",
            localField: "courseIds",
            foreignField: "_id",
            as: "courses"
        }
    }
])

This query matches Rahul's student document and retrieves the corresponding course documents.

Method 2: Many-to-Many Using a Separate Enrollment Collection

For applications where the relationship itself contains additional information, a separate collection can be useful.

For example, a student enrollment may contain:

  • Enrollment date

  • Course status

  • Payment status

  • Marks

  • Completion percentage

Create an enrollment collection:

db.enrollments.insertMany([
    {
        studentId: 1,
        courseId: 101,
        enrollmentDate: new Date("2026-01-10"),
        status: "Active"
    },
    {
        studentId: 1,
        courseId: 102,
        enrollmentDate: new Date("2026-01-12"),
        status: "Completed"
    },
    {
        studentId: 2,
        courseId: 101,
        enrollmentDate: new Date("2026-01-15"),
        status: "Active"
    }
])

Here, the enrollments collection connects students and courses.

To find all courses associated with student ID 1:

db.enrollments.aggregate([
    {
        $match: {
            studentId: 1
        }
    },
    {
        $lookup: {
            from: "courses",
            localField: "courseId",
            foreignField: "_id",
            as: "courseDetails"
        }
    },
    {
        $unwind: "$courseDetails"
    },
    {
        $project: {
            _id: 0,
            studentId: 1,
            courseName: "$courseDetails.courseName",
            enrollmentDate: 1,
            status: 1
        }
    }
])

This query retrieves the enrollment records and adds the matching course details.

When to use a separate enrollment collection:

  • When the relationship contains additional information.

  • When enrollment records need their own lifecycle.

  • When you need to query, update or report on enrollments independently.

5. Difference Between Embedded Documents and References

Both approaches are useful in MongoDB, but they solve different data modeling requirements.

Feature Embedded Documents References
Data Storage Same document Separate documents
Retrieval Often one query May require $lookup or multiple queries
Data Duplication Can occur when embedding repeated data Can reduce duplication
Updates Related data updated within the parent document Related documents updated separately
Best For Closely related, bounded data Independently managed or growing data
Example Student with profile Department with employees

Important: MongoDB does not require every relationship to be modeled using references. Choose the structure according to your application's query patterns and data growth.

6. When Should You Use Each Relationship?

Relationship Example Common Modeling Approach
One-to-One Student and profile Embedded document or reference
One-to-Many Department and employees Embedded array or references
Many-to-Many Students and courses ID arrays or separate relationship collection

Consider these points before choosing a design:

  1. How frequently will related information be retrieved together?

  2. How many related records can exist?

  3. Does related information need to be updated independently?

  4. Does the relationship contain its own additional fields?

  5. Will the document grow beyond a practical size?

MongoDB documents have a maximum BSON document size of 16 MiB. Avoid embedding unlimited or continuously growing arrays in a single document.

7. Practical Example: Student and Course Management System

Let's combine the concepts in a simple student and course management example.

Select the database:

use schoolDB

Insert students:

db.students.insertMany([
    {
        _id: 1,
        name: "Rahul",
        email: "rahul@example.com"
    },
    {
        _id: 2,
        name: "Priya",
        email: "priya@example.com"
    }
])

Insert courses:

db.courses.insertMany([
    {
        _id: 101,
        courseName: "MongoDB",
        duration: "2 Months"
    },
    {
        _id: 102,
        courseName: "JavaScript",
        duration: "3 Months"
    }
])

Create student enrollments:

db.enrollments.insertMany([
    {
        studentId: 1,
        courseId: 101,
        status: "Active"
    },
    {
        studentId: 1,
        courseId: 102,
        status: "Completed"
    },
    {
        studentId: 2,
        courseId: 101,
        status: "Active"
    }
])

Retrieve students with their enrollments:

db.students.aggregate([
    {
        $lookup: {
            from: "enrollments",
            localField: "_id",
            foreignField: "studentId",
            as: "enrollments"
        }
    }
])

Retrieve enrollment details with course information:

db.enrollments.aggregate([
    {
        $lookup: {
            from: "courses",
            localField: "courseId",
            foreignField: "_id",
            as: "courseDetails"
        }
    },
    {
        $unwind: "$courseDetails"
    }
])

This example demonstrates how separate collections can be connected to represent a Many-to-Many relationship.

8. Best Practices for MongoDB Relationship Design

Follow these best practices when designing MongoDB relationships:

  1. Design around queries: Understand how your application reads and updates data before choosing embedded documents or references.

  2. Use embedding for closely related data: Store information together when it is usually accessed together and has a reasonable size.

  3. Use references for growing relationships: Keep independently managed or potentially large collections separate.

  4. Avoid unlimited arrays: Continuously growing arrays can make documents difficult to manage.

  5. Use meaningful reference fields: Names such as studentId, departmentId and courseId make relationships easier to understand.

  6. Index frequently queried reference fields: Index fields such as studentId and departmentId when they are commonly used in queries.

  7. Use a relationship collection when needed: A separate collection is useful when the relationship contains its own details.

  8. Maintain data consistency: Plan how related documents will be updated or deleted together when required.

9. Practice Exercises

Try these exercises in MongoDB Shell:

Exercise 1: Create a users collection with an embedded profile object. This represents a One-to-One relationship.

Exercise 2: Create a departments collection and store multiple employees in an embedded array.

Exercise 3: Create separate departments and employees collections. Connect employees using departmentId.

Exercise 4: Create students and courses collections. Store multiple course IDs in each student document.

Exercise 5: Create an enrollments collection to connect students and courses.

Exercise 6: Use $lookup to retrieve all employees belonging to a department.

Exercise 7: Use $lookup to display student enrollment records with course names.

Conclusion

MongoDB supports flexible ways to represent relationships between documents. One-to-One, One-to-Many and Many-to-Many relationships can be designed using embedded documents, references or separate relationship collections.

In this tutorial, we learned how to create and retrieve each relationship using practical mongosh examples and the $lookup aggregation stage.

Choosing the right relationship structure helps make your database easier to maintain, query and scale.

In the next module, we will explore MongoDB indexing and aggregation to improve query performance and analyze data efficiently.

Frequently Asked Questions (FAQs)

1. Does MongoDB support relationships?

Yes. MongoDB supports relationships using embedded documents and references between collections.

2. What is a One-to-One relationship in MongoDB?

A One-to-One relationship means one document is associated with one related document, such as a student and their profile.

3. What is a One-to-Many relationship in MongoDB?

A One-to-Many relationship means one document is connected to multiple related documents, such as one department having many employees.

4. What is a Many-to-Many relationship in MongoDB?

A Many-to-Many relationship means multiple documents in one collection can be associated with multiple documents in another collection, such as students and courses.

5. What is the difference between embedding and referencing?

Embedding stores related data inside the same document, while referencing stores related data separately and connects it using identifiers.

6. What is $lookup in MongoDB?

$lookup is an aggregation stage used to retrieve matching documents from another collection.

7. Which relationship approach is better in MongoDB?

There is no single best approach. The choice depends on data size, query patterns, update requirements and how independently related records are managed.

Learn MongoDB with practical examples at Param Classes – Learn Today, Grow Tomorrow.

←
Post 18 of 35
→