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中则会引用消息。