MongoDB表现为$ ref vs embedded

时间:2015-10-24 17:31:32

标签: node.js performance mongodb reference

我最近开始使用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发现查询以检索用户及其主题,但它也是easyer直接查询主题。

以下是我用于检索具有第一个架构的某些用户信息的特定主题的请求:

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"}
    }}
]);

所以问题是,你怎么想?您认为哪个好的架构?

提前致谢。

1 个答案:

答案 0 :(得分:0)

更好的解决方案:使用引用来获取用户发布的主题

对于此数据库使用,通常需要考虑MMAPV1文档大小限制(16MB)。将用户,主题和注释放在一个文档中可以使文档无限制地增长。如果每个主题都是一个文本页面(1K),那么在达到限制之前,每个用户可以拥有大约16,000个主题。这看起来很大,但如果您决定在产品成熟时将图像,视频和声音放入主题中会发生什么?稍后从嵌入式模式转换为规范化模式将比现在的简单设计选择要多得多。

同样,如果评论可能会增加导致主题超过16MB的限制,那么它们应该在一个单独的集合中。不可能?大概。但是如果你正在写一些会成为Huffington Post的东西 - 请查看他们热门文章的评论。

以下是mongo对data model design

的建议