0
0
MongodbHow-ToBeginner · 4 min read

How to Model Many-to-Many Relationships in MongoDB

In MongoDB, model a many-to-many relationship by using referencing with arrays of ObjectIds in both collections or by creating a separate linking collection. This approach keeps data flexible and avoids duplication while allowing efficient queries.
📐

Syntax

To model many-to-many relationships, you typically use references between documents. Each document stores an array of ObjectId values pointing to related documents in another collection.

Alternatively, you can create a linking collection that stores pairs of references to connect documents from both sides.

  • Referencing: Store arrays of ObjectId in both collections.
  • Linking Collection: Create a separate collection with documents containing references to both related documents.
json
/* Referencing example */
{
  _id: ObjectId("..."),
  name: "Author A",
  book_ids: [ObjectId("..."), ObjectId("...")]
}

{
  _id: ObjectId("..."),
  title: "Book 1",
  author_ids: [ObjectId("..."), ObjectId("...")]
}

/* Linking collection example */
{
  _id: ObjectId("..."),
  author_id: ObjectId("..."),
  book_id: ObjectId("...")
}
💻

Example

This example shows two collections, authors and books, referencing each other to model a many-to-many relationship.

javascript
use library

// Insert authors
const author1 = db.authors.insertOne({ name: "Author A", book_ids: [] });
const author2 = db.authors.insertOne({ name: "Author B", book_ids: [] });

// Insert books
const book1 = db.books.insertOne({ title: "Book 1", author_ids: [] });
const book2 = db.books.insertOne({ title: "Book 2", author_ids: [] });

// Update authors with book references
db.authors.updateOne({ _id: author1.insertedId }, { $set: { book_ids: [book1.insertedId, book2.insertedId] } });
db.authors.updateOne({ _id: author2.insertedId }, { $set: { book_ids: [book2.insertedId] } });

// Update books with author references
db.books.updateOne({ _id: book1.insertedId }, { $set: { author_ids: [author1.insertedId] } });
db.books.updateOne({ _id: book2.insertedId }, { $set: { author_ids: [author1.insertedId, author2.insertedId] } });

// Query: Find books by Author A
const authorA = db.authors.findOne({ name: "Author A" });
const booksByAuthorA = db.books.find({ _id: { $in: authorA.book_ids } }).toArray();

booksByAuthorA;
Output
[ { _id: ObjectId("..."), title: "Book 1", author_ids: [ObjectId("...")] }, { _id: ObjectId("..."), title: "Book 2", author_ids: [ObjectId("..."), ObjectId("...")] } ]
⚠️

Common Pitfalls

  • Embedding too much data: Embedding entire related documents can cause duplication and update issues.
  • Not using references: Without references, querying many-to-many relations becomes inefficient.
  • Ignoring linking collections: For complex relations, a linking collection keeps data normalized and queries simpler.
json
/* Wrong: Embedding full related documents causes duplication */
{
  _id: ObjectId("..."),
  name: "Author A",
  books: [
    { _id: ObjectId("..."), title: "Book 1" },
    { _id: ObjectId("..."), title: "Book 2" }
  ]
}

/* Right: Use references instead */
{
  _id: ObjectId("..."),
  name: "Author A",
  book_ids: [ObjectId("..."), ObjectId("...")]
}
📊

Quick Reference

  • Use arrays of ObjectId to reference related documents.
  • Consider a linking collection for complex many-to-many relations.
  • Avoid embedding full related documents to prevent duplication.
  • Keep references consistent on both sides for easier queries.

Key Takeaways

Model many-to-many in MongoDB using arrays of ObjectId references or a linking collection.
Avoid embedding full related documents to prevent data duplication and update issues.
Keep references consistent in both collections for efficient querying.
Use a linking collection when relationships are complex or require additional attributes.
Always design your schema based on your query patterns and data update needs.