Tutorials Logic, IN +91 8092939553 info@tutorialslogic.com
FAQs Support
Navigation
Home About Us Contact Us Blogs FAQs
Tutorials
All Tutorials
Services
Academic Projects Resume Writing Interview Questions Website Development
Compiler Tutorials

MongoDB Relationships

Modelling Relationships in MongoDB

MongoDB supports two primary strategies for representing relationships: embedding (denormalization) and referencing (normalization). Unlike SQL, there are no foreign key constraints — you manage relationships in application logic or through the aggregation pipeline.

Embedded Documents

One-to-One and One-to-Many Embedded
// ONE-TO-ONE EMBEDDED: User with address
{
  "_id": ObjectId("u1"),
  "name": "Alice Johnson",
  "address": { "street": "123 Main St", "city": "New York", "zip": "10001" }
}

// ONE-TO-MANY EMBEDDED: Post with comments (bounded array)
{
  "_id": ObjectId("p1"),
  "title": "Getting Started with MongoDB",
  "comments": [
    { "user": "Bob",   "text": "Great article!", "date": ISODate("2024-01-10") },
    { "user": "Carol", "text": "Very helpful.",   "date": ISODate("2024-01-11") }
  ]
}

// Query embedded field
db.posts.find({ "comments.user": "Bob" })

// Update embedded array element using positional operator
db.posts.updateOne(
  { _id: ObjectId("p1"), "comments.user": "Bob" },
  { $set: { "comments.$.text": "Updated comment!" } }
)

Manual References

One-to-Many Referenced with $lookup
// users collection
{ "_id": ObjectId("u1"), "name": "Alice Johnson", "email": "alice@example.com" }

// orders collection — each order references the user
{ "_id": ObjectId("o1"), "userId": ObjectId("u1"), "total": 1299.99, "status": "shipped" }
{ "_id": ObjectId("o2"), "userId": ObjectId("u1"), "total": 45.00,   "status": "pending" }

// Join using $lookup aggregation
db.users.aggregate([
  { $match: { _id: ObjectId("u1") } },
  { $lookup: {
      from: "orders",
      localField: "_id",
      foreignField: "userId",
      as: "orders"
  }},
  { $project: { name: 1, email: 1, orderCount: { $size: "$orders" }, orders: 1 } }
])

Many-to-Many Relationships

Many-to-Many with Arrays of References
// Students and Courses — many-to-many
// students collection
{
  "_id": ObjectId("s1"),
  "name": "Bob Smith",
  "enrolledCourses": [ObjectId("c1"), ObjectId("c2")]
}

// courses collection
{
  "_id": ObjectId("c1"),
  "title": "MongoDB Fundamentals",
  "enrolledStudents": [ObjectId("s1"), ObjectId("s2")]
}

// Find all courses a student is enrolled in
db.courses.find({ _id: { $in: [ObjectId("c1"), ObjectId("c2")] } })

// Add a student to a course
db.courses.updateOne(
  { _id: ObjectId("c1") },
  { $addToSet: { enrolledStudents: ObjectId("s3") } }
)
db.students.updateOne(
  { _id: ObjectId("s3") },
  { $addToSet: { enrolledCourses: ObjectId("c1") } }
)
Embed vs Reference Decision Guide
// EMBED when:
// - Data is always accessed together with the parent
// - The sub-document is small and bounded (e.g., max 10-20 items)
// - The sub-document is not shared across multiple parents
// - You want atomic reads/writes in a single operation

// REFERENCE when:
// - Data is accessed independently of the parent
// - The array could grow unboundedly (e.g., all comments on a viral post)
// - The same data is referenced by multiple documents
// - The sub-document is large and rarely needed

// Example: User profile — EMBED (always needed together)
{ "_id": ObjectId("u1"), "name": "Alice", "profile": { "bio": "...", "avatar": "..." } }

// Example: User orders — REFERENCE (many orders, accessed separately)
// orders: { userId: ObjectId("u1"), total: 99.99, ... }
// db.orders.find({ userId: ObjectId("u1") })

Ready to Level Up Your Skills?

Explore 500+ free tutorials across 20+ languages and frameworks.