我想设计一个带有一些评论的问题结构。注释应该使用哪种关系:嵌入还是引用?
一个带有注释的问题,比如stackoverflow,会有这样的结构:
Question
title = 'aaa'
content = 'bbb'
comments = ???
一开始,我想使用嵌入式注释(我认为MongoDB中推荐使用embed),像这样:
Question
title = 'aaa'
content = 'bbb'
comments = [ { content = 'xxx', createdAt = 'yyy'},
{ content = 'xxx', createdAt = 'yyy'},
{ content = 'xxx', createdAt = 'yyy'} ]
这很清楚,但我担心这种情况:如果我想编辑一个指定的评论,我如何获得它的内容和它的问题?没有_id让我找到一个,也没有question_ref让我找到它的问题。(也许有一种方法可以做到这一点没有_id和question_ref?)
我必须使用ref而不是embed吗?然后我必须为评论创建一个新的集合吗?
是的,我们可以使用文件中的参考资料。就像SQL i连接一样填充另一个文档。在MongoDB中,它们没有连接来将一个关系文档映射到多个关系文档。相反,我们可以使用populate来实现我们的场景。
var mongoose = require('mongoose')
, Schema = mongoose.Schema
var personSchema = Schema({
_id : Number,
name : String,
age : Number,
stories : [{ type: Schema.Types.ObjectId, ref: 'Story' }]
});
var storySchema = Schema({
_creator : { type: Number, ref: 'Person' },
title : String,
fans : [{ type: Number, ref: 'Person' }]
});
填充是自动用其他集合中的文档替换文档中的指定路径的过程。我们可以填充单个文档、多个文档、普通对象、多个普通对象或从查询返回的所有对象。让我们来看一些例子。
更多信息请访问:http://mongoosejs.com/docs/populate.html
MongoDB提供了无模式的自由,如果没有考虑或计划好,这个特性可能会导致长期的痛苦,
有2个选项,嵌入或引用。我不会详细解释定义,因为上面的答案已经很好地定义了它们。
当嵌入时,你应该回答一个问题,你嵌入的文档是否会增长,如果是,那么有多少(记住每个文档有16mb的限制)所以,如果你有一个帖子的评论,什么是评论计数的限制,如果这个帖子病毒式传播,人们开始添加评论。在这种情况下,引用可能是更好的选择(但甚至引用也会增长,达到16mb的限制)。
因此,如何平衡它,答案是不同模式的组合,检查这些链接,并根据您的用例创建自己的混合和匹配。
https://www.mongodb.com/blog/post/building-with-patterns-a-summary
https://www.mongodb.com/blog/post/6-rules-of-thumb-for-mongodb-schema-design-part-1