Mongoose:引用“Schema.ObjectId”而不是直接使用模式名称之间的区别?

假设我有以下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'}], ... }); 

主要区别在于Meeting模型embeddedMessageSchema (反规范化),而Meeting2模型引用它(规范化)。 在select上的差异归结到您的模型devise,这主要取决于你如何查询和更新你的数据。 一般来说,如果子文档很小,并且数据不会频繁更改,则可能需要使用embedded式模式devise方法。 另外,如果Message数据增长很less,则可以考虑对规范进行非规范化。 embedded式方法允许您执行优化的读取,因此可以更快,因为您将只执行单个查询,因为所有数据都驻留在同一个文档中。

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

您可以使用embedded和引用的混合,即创build一个包含频繁访问的数据的子文档数组,但引用实际文档以获取更多信息。

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

Meetings消息字段包含Message对象的数组,而Meetings2消息字段包含Message Id的数组。

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

可以写成

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

ref只是mongoose的一个辅助函数,使填充消息更容易。

所以总结。 在会议中,您将消息embedded到数组中,而在Meetings2中则会引用消息。