Welcome to the next lesson of our "Schemas and Relations" course! Previously, we explored one-to-one and one-to-many relations in MongoDB. Now, we will dive into the realm of many-to-many relations in MongoDB, examining how to model these relationships using both embedded documents and references.
A many-to-many relation occurs when multiple entities of one type are associated with multiple entities of another type. For example, consider authors and books: an author can write multiple books, and a book can have multiple authors. This establishes a many-to-many relation between authors and books.
Similar to one-to-one and one-to-many relations, we can represent many-to-many relationships in MongoDB using two primary methods:
_id
values of multiple documents are stored in an array within another document, creating references to them.Embedded documents in MongoDB allow you to store related data within a parent document, making it easy to retrieve all the information in a single query. This method is suitable when the "many" side of the relation has a manageable number of elements. However, it can lead to data duplication.
Here's an example representing authors and books using embedded documents:
JavaScript1use library_db 2 3db.booksEmbedded.insertMany([ 4 { 5 title: "Good Omens", 6 authors: [ 7 { name: "Neil Gaiman" }, 8 { name: "Terry Pratchett" } 9 ], 10 published_year: 1990 11 }, 12 { 13 title: "American Gods", 14 authors: [ 15 { name: "Neil Gaiman" } 16 ], 17 published_year: 2001 18 } 19]);
In this code snippet:
booksEmbedded
collection using insertMany()
.title
, authors
array, and published_year
. The authors
array includes embedded documents representing each author.This setup efficiently represents the many-to-many relationship between authors and books using embedded documents. Notice that we have data duplication for Neil Gaiman in the authors
array of the respective books.
Using references becomes beneficial when the "many" side of the relation grows significantly or when multiple documents need to link to the same data. References store the _id
value of one document in another, maintaining normalized data and avoiding duplicity. However, this approach requires multiple queries or an aggregate query to retrieve related data.
Here's an example using references to represent authors and books:
JavaScript1use library_db 2 3const authorId1 = new ObjectId("507f1f77bcf86cd799439011"); 4const authorId2 = new ObjectId("507f1f77bcf86cd799439012"); 5 6// Insert authors 7db.authors.insertMany([ 8 { _id: authorId1, name: "Neil Gaiman" }, 9 { _id: authorId2, name: "Terry Pratchett" } 10]); 11 12// Insert books with author ObjectId references 13db.books.insertMany([ 14 { 15 title: "Good Omens", 16 authors: [authorId1, authorId2], 17 published_year: 1990 18 }, 19 { 20 title: "American Gods", 21 authors: [authorId1], 22 published_year: 2001 23 } 24]);
In this code snippet:
authors
collection using insertMany()
, each with a unique _id
.books
collection using insertMany()
, with each book referencing the _id
values of its authors in the authors
array.This approach efficiently maintains a many-to-many link between the authors and books using references, avoiding data duplication. However, keep in mind that you need to make multiple database calls or use an aggregation query to fetch the complete related data.
In this lesson, you learned about many-to-many relations in MongoDB and explored two methods to implement them: embedded documents and references. Use embedded documents when the related data isn't extensive and does not require linking from multiple documents. When the data volume is larger or needs to be referenced by multiple documents, opting for references is more appropriate. Up next, you'll get hands-on practice to solidify your understanding of these concepts. Keep coding and enjoy your MongoDB journey!