猫鼬:引用" Schema.ObjectId"之间的区别而不是直接使用架构名称?

时间:2015-10-28 09:20:50

标签: node.js mongodb mongoose database nosql

假设我有以下MessageSchema模型:

    var MessageSchema = new Schema({
      userId: String,
      username: String,
      message: String,
      date: Date 
    });
    mongoose.model('Message', MessageSchema)   

有人可以告诉我以下两种会议模式的实现之间的区别吗?感谢。

    var Meetings = new Schema({
      _id: ObjectId,
      name: String,
      messages: [MessageSchema],
      ... 
    });

    var Meetings2 = new Schema({
      _id: ObjectId,
      name: String,
      messages: [{type: Schema.ObjectId, ref: 'Message'}],
      ... 
    });

2 个答案:

答案 0 :(得分:1)

会议消息字段包含Message对象数组,而 Meetings2 消息字段包含消息ID的数组。

var Meetings2 = new Schema({
      ...
  messages: [{type: Schema.ObjectId, ref: 'Message'}],
      ... 
});

可以写成

var Meetings2 = new Schema({
      ...
  messages: [Schema.ObjectId],
      ... 
});

ref 只是mongoose中的辅助函数,可以更轻松地populate消息。

总结一下。在Meetings中,您将消息嵌入到数组中,而在Meetings2中,您可以引用消息。

答案 1 :(得分:1)

主要区别在于Meeting模型嵌入MessageSchema(非规范化),而Meeting2模型引用它(规范化)。选择的差异归结为您的模型设计,这主要取决于您查询和更新数据的方式。通常,如果子文档很小并且数据不经常更改,您可能希望使用嵌入式架构设计方法。此外,如果Message数据少量增长,请考虑对模式进行非规范化。嵌入式方法允许您进行优化读取,因此可以更快,因为您只执行单个查询,因为所有数据都驻留在同一文档中。

另一方面,如果您的Message文档非常大,请考虑引用,以便将它们保存在您可以引用的单独集合中。确定引用方法的另一个因素是文档是否大量增长。另一个重要的考虑因素是数据变化(波动性)与其阅读方式的频率。如果定期更新,那么引用是一种很好的方法。这种方式可以增强快速写入。

您可以使用嵌入和引用的混合,即使用频繁访问的数据创建一个子文档数组,但需要参考实际文档以获取更多信息。

一般的经验法则是,如果您的应用程序的查询模式是众所周知的,并且数据往往只能以一种方式访问​​,那么嵌入式方法效果很好。如果您的应用程序以多种方式查询数据,或者您无法预测数据查询模式,则更为规范化的文档引用模型将适用于此类情况。