我最近开始了一个使用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的建议

09-10 12:53
查看更多