乐闻世界logo
搜索文章和话题

Many - to -many mapping with Mongoose

1个答案

1

In Mongoose, implementing many-to-many mapping relationships generally involves two methods: using references (refs) or using embedded documents. To illustrate this more concretely, consider an example where we have a Book and Author data model. A book can have multiple authors, and an author can also write multiple books.

Using References (Refs)

This method involves storing an array of ObjectId references to related documents within each model. This is a common approach because it maintains document independence between collections. Here is an example of how to implement it:

Book Model:

javascript
const mongoose = require('mongoose'); const Schema = mongoose.Schema; const bookSchema = new Schema({ title: String, authors: [{ type: Schema.Types.ObjectId, ref: 'Author' }] }); const Book = mongoose.model('Book', bookSchema);

Author Model:

javascript
const mongoose = require('mongoose'); const Schema = mongoose.Schema; const authorSchema = new Schema({ name: String, books: [{ type: Schema.Types.ObjectId, ref: 'Book' }] }); const Author = mongoose.model('Author', authorSchema);

Using this approach, when you want to retrieve books and their author lists, you need to perform a populate operation to replace ObjectId values with the corresponding documents:

javascript
Book.find({}).populate('authors').exec(function(err, books) { if (err) { // handle error } // books now have their authors array populated with author data });

Similarly, if you want to retrieve authors and their book lists:

javascript
Author.find({}).populate('books').exec(function(err, authors) { if (err) { // handle error } // authors now have their books array populated with book data });

Using Embedded Documents (Embedded Documents)

Another approach is to use embedded documents. This method involves storing a document as part of another document. Note that this method may not be suitable for all scenarios because it can introduce data redundancy and complicate updates. If data updates frequently or the embedded data is large, this approach is generally not recommended.

Assuming business rules permit this, we can design the models as follows:

Book Model (Embedding Author Data):

javascript
const mongoose = require('mongoose'); const Schema = mongoose.Schema; const bookSchema = new Schema({ title: String, authors: [{ name: String, // Other author fields }] }); const Book = mongoose.model('Book', bookSchema);

Author Model (Embedding Book Data):

javascript
const mongoose = require('mongoose'); const Schema = mongoose.Schema; const authorSchema = new Schema({ name: String, books: [{ title: String, // Other book fields }] }); const Author = mongoose.model('Author', authorSchema);

In this case, you do not need to perform a populate operation because all related data is directly nested within the document. However, whenever an author publishes a new book or a book adds a new author, you must update both documents in the collections, which increases maintenance effort.

Overall, for maintainability and flexibility, using references (refs) with the populate method to implement many-to-many mapping relationships is more common and recommended.

2024年6月29日 12:07 回复

你的答案