猫鼬设计模型中的嵌入式文档与参考?

Posted

技术标签:

【中文标题】猫鼬设计模型中的嵌入式文档与参考?【英文标题】:Embedded document vs reference in mongoose design model? 【发布时间】:2014-02-13 15:40:31 【问题描述】:

假设我正在使用 Node.js 和 mongoose 构建一个讨论论坛。一个用户可以有多个论坛,一个论坛可以有多个cmet。用户也可以邀请其他用户加入论坛。因此,我的问题是关于使用参考或嵌入文档的模型设计!

如果我使用嵌入式文档,它看起来像:

var Comment = new Schema( ... );

var Forum = new Schema(
    title: type: String,
    content: type: String,
    comments: [Comment],
    attendees: [User]
);

var User = new Schema(
    name: type: String,
    email: type: String,
    forums: [Forum]
);

var Account = mongoose.model('Account', User);

使用上述设计,我遇到了以下问题:当用户向论坛添加评论,并且该论坛在我的论坛中时,我认为我无法在我的论坛列表中获得新评论的更新.我吗?你知道如何让嵌入的文档在这种情况下工作吗?

因此,我正在考虑在 mongoose 中使用 reference。在这种情况下,我将有两个集合:AccountForum。在这种情况下,向论坛添加新评论不是问题。我说的对吗?

reference 会比 嵌入式文档 更好吗?

提前致谢,

【问题讨论】:

以下答案之一对您有帮助吗? 这篇文章对我理解嵌入很有帮助。 【参考方案1】:

这主要取决于您将如何查询和更新数据。在这种情况下,一致性和文档大小也很重要。以下是关于何时引用或嵌入文档的一个很好的总结:

嵌入:

小子文档 不定期更改的数据 最终的一致性是可以接受的 少量增长的文档 您经常需要执行第二次查询才能获取的数据 快速读取

参考:

大型子文档 易变数据 需要立即保持一致性 大量增长的文档 您通常会从结果中排除的数据 快速写入

这是我读过的一本关于 mongo 的书的摘录。这些只是一般规则,但根据我的经验,使用它们可以非常清楚地在大多数情况下引用还是嵌入。

在这种情况下,我宁愿参考论坛。但请考虑您的所有要求。例如,如果您从用户引用论坛并且您需要查询特定论坛的所有用户,则在这种情况下查询可能会很慢。如果我是你,我会列出我需要的所有内容,然后使用一般规则会在嵌入和引用的利弊之间找到平衡。

希望对你有帮助!

【讨论】:

我认为现在应该将其标记为答案。 @AlexFord 嗯,我不会打赌,一:自从“立即一致性”以来,他一直在阅读什么 MongoDB 书?我不确定他的意思是什么,但 MongoDB 中的手动引用没有提供内置的一致性 @Sammaye “即时一致性” - 许多其他人引用的一个对象。如果您更新它,您将从引用该对象的任何对象中获取最新数据。 “最终一致性” - 一个对象嵌套在许多其他对象中,因此如果更改它,则必须在任何地方更改它,因此您可能会遇到其中一些更新但有些没有更新的情况。当然,这与事务一致性无关,例如当您需要更新 tow 对象或不更新时。【参考方案2】:

我个人喜欢在像你这样的情况下做参考。通过这种方式,我可以从用户那里获得评论,从论坛获得用户,从评论获得论坛,从用户获得论坛等,而无需担心进行复杂的嵌入式文档查询。我什至不费心存储嵌入式参考文档。如果论坛和 cmets 之间存在一对多关系,那么我会在评论中存储论坛参考,而在论坛上没有评论参考,因为当您从 cmets 集合中添加/删除 cmets 时,您还必须删除嵌入的参考论坛cmets集合中的文档。

我可以使用论坛参考从评论中查询论坛,我可以通过查询该论坛参考的 cmets 集合来获取论坛的所有 cmets(这只是一个 ID 号,直到 mongoose 在幕后为您填充它)。

【讨论】:

以上是关于猫鼬设计模型中的嵌入式文档与参考?的主要内容,如果未能解决你的问题,请参考以下文章

在猫鼬中仅更改整个嵌入式文档数组的一个字段

在猫鼬中仅更改整个嵌入式文档数组的一个字段

如何更新具有嵌入文档的猫鼬数组中的许多元素

如何在猫鼬的嵌入式文档中填充字段?

将猫鼬模型引导到 BackboneJS

嵌入式数组中的猫鼬更新对象