Facebook Pixel

How to Handle Relationships in MongoDB With Mongoose ref and populate

MongoDB handles relationships differently from SQL. Here is how to do it with Mongoose ref and populate.

How to Handle Relationships in MongoDB With Mongoose ref and populate

MongoDB handles relationships differently from SQL. Here is how to do it with Mongoose ref and populate.

Reference Approach

Store the id of a related document as a field. For example, a Post has author: { type: mongoose.Schema.Types.ObjectId, ref: 'User' }. This references the User collection without embedding.

Embed Approach

Store related data directly in the document. For example, a Post has comments: [{ text: String, author: String }] embedded. No reference; the comments live inside the post document.

When to Reference

When related data is shared (a user's posts), large (all comments), or frequently accessed independently. Referencing avoids data duplication and keeps documents small.

When to Embed

When related data is always read with the parent (a user's address), small in number, and rarely accessed independently. Embedding avoids extra queries for related data.

Using populate

When you reference, use populate to fetch the related data: Post.find().populate('author'). This runs a second query to fetch the author for each post, similar to a SQL join.

Common Mistake: N+1 Queries

Using populate in a loop or without batching causes N+1 queries. For lists, use populate once on the find query, not per item in a loop. Mongoose batches populate efficiently when called on the query.

The Takeaway

In MongoDB with Mongoose, reference large or shared data (use ref and populate to fetch), embed small always-read-together data. Reference for users and posts; embed for addresses and small nested data. Use populate to join referenced data in one query.

Use ref to store ObjectId references for large or shared data, and populate to fetch related data. Embed small, always-read-together data directly in the document. Choose based on data size and access patterns.

Embed stores related data directly in the document (fast reads, duplication). Reference stores the related document's id, requiring populate to fetch it. Embed for small always-read-together data; reference for large or shared data.

populate tells Mongoose to fetch the referenced document. Post.find().populate('author') runs a second query to fetch the author for each post, similar to a SQL join. This is how you get related data when using references.

Embed when data is small, always read with the parent, and rarely accessed independently (a user's address). Reference when data is large, shared (a post's author), or frequently accessed independently (comments on a post).

Calling populate per item in a loop instead of on the find query. This causes N+1 queries instead of one. For lists, call populate once on the find query; Mongoose batches it efficiently, avoiding the N+1 problem.

Ready to master Node.js completely?

Want to upskill yourself, crack your next interview, and get your dream job? Join our comprehensive course to dive deeper with high-quality video tutorials, solve interview questions, and a premium community.

Please Login.
Please Login.
Please Login.
Please Login.
Please Login.
Please Login.
Please Login.
Please Login.
Please Login.
Please Login.
Please Login.
Please Login.