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

Many - to -many mapping with Mongoose

4 个月前提问
3 个月前修改
浏览次数14

1个答案

1

在Mongoose中,实现多对多的映射关系一般有两种方法:使用引用(refs)或者使用嵌入式文档(embedded documents)。为了更具体地说明这一点,我们可以考虑一个例子,比如有一个书籍(Book)和作者(Author)的数据模型,一本书可以有多个作者,一个作者也可能写了多本书。

使用引用(Refs)

这种方法涉及到在每个模型中存储相关联另一个模型的ObjectId数组。这是一种常见的方法,因为它允许在集合之间保持文档的独立性。下面是如何实现的示例:

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);

使用这种方法,当您想要获取书籍和它们的作者列表时,您需要执行一个populate操作,这样可以替换ObjectId为相应的文档:

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

同样的,如果您想要获取作者及其所写的书籍列表:

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

使用嵌入式文档(Embedded Documents)

另一种方法是使用嵌入式文档。这种方法涉及将一个文档作为另一个文档的一部分存储。需要注意的是,这种方法可能不适合所有情况,因为它会导致数据的冗余,且更新起来较为复杂。如果数据更新频繁,或者嵌入的数据很大,通常不推荐使用这种方法。

假设我们的业务规则允许这种情况,我们可以这样设计模型:

Book Model (嵌入Author数据):

javascript
const mongoose = require('mongoose'); const Schema = mongoose.Schema; const bookSchema = new Schema({ title: String, authors: [{ name: String, // 其他关于作者的字段 }] }); const Book = mongoose.model('Book', bookSchema);

Author Model (嵌入Book数据):

javascript
const mongoose = require('mongoose'); const Schema = mongoose.Schema; const authorSchema = new Schema({ name: String, books: [{ title: String, // 其他关于书籍的字段 }] }); const Author = mongoose.model('Author', authorSchema);

在这种情况下,我们不需要执行populate操作,因为所有相关联的数据已经直接嵌套在文档中了。但是,每次一个作者发布新书或者书籍增加新作者时,都需要同时更新两个集合中的文档,这会导致更多的维护工作。

总的来说,通常情况下,为了维护性和灵活性,使用引用(refs)和populate方法来实现多对多的映射关系是更加常见和推荐的做法。

2024年6月29日 12:07 回复

你的答案