Mongoose:引用 "Schema.ObjectId" 与直接使用模式名称之间的区别?

Mongoose: Difference between referencing "Schema.ObjectId" instead of directly using the schema name?

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

Meetings 消息字段包含消息对象数组,而 Meetings2 消息字段包含消息 ID 数组。

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

可以写成

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

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

综上所述。在 Meetings 中,您将消息嵌入数组中,而在 Meetings2 中,您引用消息。

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

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

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

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