我最近开始了一个使用mongodb和nodejs构建一个宁静的Web服务的项目。不幸的是mongodb对我来说是一个新手,来自关系数据库世界,我在问自己很多问题。
让我向您解释我的问题:
目标是建立一种具有社交功能的内容管理系统,例如用户可以发布可以共享和评论的主题。
我有两种方法可以做到这一点,一种是使用参考来获取用户发布的主题,第二种是使用主题作为用户的嵌入式文档而不是参考。
所以基本上我可以拥有以下两种模式:
var UserSchema = new Schema({
username: {
type: String,
unique: true,
required: true
},
password: {
type: String,
required: true
},
name: {
type: String
},
first_name: String,
phone: String,
topics: [Topic.schema]
});
var TopicSchema = new Schema({
_creator: {
type: String,
ref: 'User'
},
description: String,
comments: [Comments.schema],
shared_with: [{
type: Schema.ObjectId,
ref: 'User'
}] //[{ type: String, ref: 'User'}]
});
var CommentSchema = new Schema({
_creator: {
type: String,
require: true
},
text: {
type: String,
required: true
},
});
和
var UserSchema = new Schema({
username: {
type: String,
unique: true,
required: true
},
password: {
type: String,
required: true
},
name: {
type: String
},
first_name: String,
phone: String,
topics: [{ type: Schema.ObjectId, ref: 'Topics'}]
});
var TopicSchema = new Schema({
_creator: {
type: String,
ref: 'User'
},
description: String,
comments: [Comments.schema],
shared_with: [{
type: Schema.ObjectId,
ref: 'User'
}] //[{ type: String, ref: 'User'}]
});
var CommentSchema = new Schema({
_creator: {
type: String,
require: true
},
text: {
type: String,
required: true
},
});
因此,第一个模式使用1个用户文档集合,第二个模式使用1个用户文档集合和1个主题主题,这意味着例如要进行2次查找查询以检索用户及其主题,但是查询起来也更容易直接的话题。
这是我使用第一个模式检索具有一些用户信息的特定主题的请求:
User.aggregate([
{$match: {
"topics._id":{$in:[mongoose.Types.ObjectId('56158c314861d2e60d000003')]}
}},
{ $unwind:"$topics" },
{$match: {
"topics._id":{$in:[mongoose.Types.ObjectId('56158c314861d2e60d000003')]}
}},
{ $group: {
_id: {
_id:"$_id",
name:"$name",
first_name:"$first_name"
},
topics:{ "$push": "$topics"}
}}
]);
所以问题是,您怎么看?您认为哪种方案是好的?
提前致谢。
最佳答案
更好的解决方案:使用参考获取用户发布的主题
对于此数据库的使用,通常需要考虑MMAPV1文档的大小限制(16MB)。将用户,主题和评论放在一个文档中可以使文档不受限制地增长。如果每个主题都是一页文本(1K),则在达到限制之前,每个用户可能有大约16,000个主题。这似乎很大,但是如果您决定在产品成熟时将图像,视频和声音作为主题,会发生什么?如今,从嵌入式模式转换为规范化模式将比今天的简单设计选择大得多。
同样,如果评论可能增长而导致主题超过16MB限制,则应将它们放在单独的集合中。不太可能吗?大概。但是,如果您编写的内容会变成Huffington Post,请查看有关其热门文章的评论。
这是mongo关于data model design的建议