Relationships: Embedding vs Referencing

intermediate
13 min

Relationships: Embedding vs Referencing

Every application has relationships: users have orders, posts have comments, students attend courses. In MongoDB you model each relationship with one of two tools, embedding or referencing, and choosing correctly is the heart of document data modeling. This CodeYourCraft lesson gives you the decision framework, worked examples of each pattern, and the hybrid patterns professionals actually use.

The Two Options

Embedding stores related data inside the parent document. Referencing stores related data in its own collection and links it by _id:

javascript
// Embedded: address lives inside the customer { _id: 1, name: 'Meera', address: { city: 'Pune', pin: '411001' } } // Referenced: orders point at their customer { _id: 501, customerId: 1, total: 4499, items: [...] }

Embedding gives you everything in one read and atomic single-document updates. Referencing keeps documents small, avoids duplication, and lets the related data grow without limit.

One-to-One and One-to-Few: Embed

A user and their profile settings, an order and its shipping address: these belong together. The same goes for one-to-few relationships, where the few side is small and bounded:

javascript
{ _id: ObjectId('...'), name: 'Meera Kulkarni', addresses: [ { label: 'home', city: 'Pune' }, { label: 'office', city: 'Mumbai' } ] }

Nobody has ten thousand addresses, so the array stays bounded, and the profile page needs exactly one query.

One-to-Many: Reference from the Many Side

When the many side is large or unbounded, such as a customer with years of orders, embed nothing and store the reference on the child:

javascript
// orders collection { _id: ObjectId('...'), customerId: ObjectId('...'), total: 8999, createdAt: ISODate('...') } // All orders for a customer (index customerId!) db.orders.find({ customerId: someId }).sort({ createdAt: -1 })

The parent stays small forever, and the child collection can be queried, indexed, and aged out independently.

Many-to-Many: Arrays of References

Students and courses, posts and tags: store an array of _ids on one side, usually the side you query from most often:

javascript
// students { _id: 's1', name: 'Rohan', courseIds: ['c101', 'c204'] } // Courses for a student db.courses.find({ _id: { $in: student.courseIds } }) // Students in a course (multikey index on courseIds makes this fast) db.students.find({ courseIds: 'c101' })

Unlike SQL, you rarely need a junction collection unless the relationship itself carries data, such as an enrollment grade.

Hybrid Patterns: The Professional Middle Ground

Extended reference: store the reference plus a small copy of the fields you always display, such as customerId along with customerName on each order. Reads skip the join; renames require a background sync.

Subset pattern: embed the newest or most relevant few items and keep the full history referenced, like the ten most recent reviews on a product document with the rest in a reviews collection. Hot reads stay single-document while data stays bounded.

The Decision Checklist

Ask these questions in order: Is the related data always read with the parent? How many related items can exist at maximum, and is that bounded? How often does the related data change, and is it updated independently? Do you need to query the related data on its own? Frequent joint reads with a bounded size favor embedding; independent growth, independent queries, or frequent independent updates favor referencing.

Key Takeaways

  • Embed one-to-one and bounded one-to-few relationships for single-read pages.
  • Reference unbounded one-to-many data from the child side, and index the foreign key.
  • Model many-to-many with arrays of _ids plus $in queries and multikey indexes.
  • Extended reference and subset patterns combine the strengths of both approaches.
  • Bounded plus read-together means embed; unbounded or independent means reference.

Next we leave the shell and connect MongoDB to a real application using Node.js and Mongoose.

Relationships: Embedding vs Referencing - MongoDB | CodeYourCraft | CodeYourCraft