Back to Interview PrepGet interview ready with AILearn each topic the way interviewers ask it, then answer like you would in the interview.
Course progress0/12 chapters · 0%

Chapter 6 of 13

~12 min

Relationships: Embedding vs. Referencing

MongoDB gives you two fundamentally different ways to model a relationship between two pieces of data: embedding one document inside another, or storing a reference and looking it up separately. Choosing correctly for each relationship is one of the most consequential decisions in a MongoDB schema.

Embedding: Storing Related Data Together

Embedding nests one document (or an array of documents) directly inside its parent. It is the natural choice when the embedded data is only ever accessed in the context of its parent, does not grow unboundedly, and does not need to be queried or updated independently very often. The upside is a single read retrieves everything you need; the downside is the 16MB document size limit and the fact that deeply nested arrays that grow without bound become slow to update and can eventually hit that limit.

queries.js
const user = {
  _id: ObjectId("..."),
  name: "Ada Lovelace",
  addresses: [
    { type: "home", city: "London", zip: "SW1A 1AA" },
    { type: "work", city: "Cambridge", zip: "CB2 1TN" }
  ]
};
Embedding a small, bounded set of addresses inside a user

Referencing: Storing a Pointer Instead

Referencing stores just the related document's _id (or another identifier) and requires a separate query - either a manual second find(), or a $lookup aggregation stage, or Mongoose's populate() - to fetch the full related document. Referencing is the right call when the related data is large, changes independently, is shared across many parents (so duplicating it would multiply update work), or grows without a natural bound.

queries.js
// orders collection references products rather than embedding
// full product details, since products are shared, updated
// independently, and can be large.
const order = {
  _id: ObjectId("order1"),
  userId: ObjectId("user1"),
  items: [
    { productId: ObjectId("prod1"), quantity: 2 },
    { productId: ObjectId("prod2"), quantity: 1 }
  ]
};
Referencing a large, independently-updated document

One-to-Few, One-to-Many, and Many-to-Many

One-to-few relationships (a user with a handful of addresses) are usually embedded directly, since the array stays small and bounded. One-to-many relationships where the "many" side can grow large or unbounded (a blog with thousands of comments across all posts, or a customer with years of orders) are usually referenced, often storing the reference on the "many" side (each comment stores a postId) rather than as a growing array on the "one" side. Many-to-many relationships (students and courses, where each belongs to several of the other) are almost always modeled with references on both sides, or with a small join-style collection when the relationship itself carries extra data (like an enrollment date).

queries.js
// Instead of an ever-growing array of comments inside a post
// (risking hitting the 16MB limit on a popular post), store
// each comment as its own document referencing the post:
db.comments.insertOne({
  postId: ObjectId("post1"),
  author: "Grace",
  text: "Nice explanation!"
})

db.comments.find({ postId: ObjectId("post1") })
One-to-many with the reference on the "many" side

Populate: Resolving References in Mongoose

When using Mongoose, a referenced field is typically declared with a `ref` to another model, and `.populate()` replaces the stored _id with the full referenced document at query time - roughly equivalent to a client-side join. It is convenient, but it is worth remembering it issues an additional query behind the scenes, so populating deeply nested or very large result sets can add real latency if used carelessly.

Coding challenge

You are modeling a university system: students can enroll in many courses, and each course has many students. Describe how you would model this many-to-many relationship in MongoDB and why embedding is a poor fit here.

// Write your solution here

Answer every question below to mark this chapter as complete.

Quiz Yourself

Score: 0/4

1. When is embedding generally the better choice over referencing?

2. Why is storing an ever-growing array of comments directly inside a blog post document risky?

3. What does Mongoose's .populate() do?

4. What is a common way to model a many-to-many relationship, like students and courses, in MongoDB?

You're viewing a free lesson. Sign up free to track your progress and unlock the full course.Sign up freeSign in