繁体   English   中英

MongoDB和Mongoose:文档参考ID的嵌套数组

[英]MongoDB and Mongoose: Nested Array of Document Reference IDs

我一直在研究MongoDB,并遇到了一种特别有趣的模式,用于存储文档之间的关系。 此模式涉及父文档,其中包含引用子文档的ID数组,如下所示:

//Parent Schema
export interface Post extends mongoose.Document {
  content: string;
  dateCreated: string;
  comments: Comment[];
}

let postSchema = new mongoose.Schema({
  content: {
    type: String,
    required: true
  },
  dateCreated: {
    type: String,
    required: true
  },
  comments: [{ type: mongoose.Schema.Types.ObjectId, ref: 'Comment' }] //nested array of child reference ids
});

和被引用的孩子:

//Child Schema
export interface Comment extends mongoose.Document {
  content: string;
  dateCreated: string;
}

let commentSchema = new mongoose.Schema({
  content: {
    type: String,
    required: true
  },
  dateCreated: {
    type: String,
    required: true
  }
});

在我从前端发送请求以创建新评论之前,这一切似乎都很好。 该请求必须包含Post _id(以更新帖子)和新的Comment,这两者都是使用常规关系数据库时将发送的请求所共有的。 当需要将新的注释写入数据库时​​,将出现问题。 而不是像在普通的关系数据库中那样进行一次数据库写入,我必须进行2次写入和1次读取。 第一次写入以插入新的Comment并检索_id。 然后,通过与请求一起发送的Post _id进行读取以检索Post,这样我就可以将新的Comment _id推送到嵌套的引用数组。 最后,最后写入以将Post更新回数据库。

这似乎效率极低。 我的问题有两个:

  1. 有没有更好/更有效的方法来处理这种关系模式(父级包含子级参考ID的数组)?

  2. 如果不是这样,与使用A)将父_id存储在类似于传统外键的子级属性中或使用B)利用MongoDB文档并将Comments数组存储为A相比,使用此模式有什么好处?与注释的参考ID数组相对。

预先感谢您的见解!

关于第一个问题:

您特别要求一种更好的方式来处理存储在父代中的子代ID。 我很确定,如果必须使用这种模式,那么没有更好的方法来解决这个问题。

但是关系数据库中也存在此问题。 如果要将帖子保存在关系数据库中(使用该模式),则还必须首先创建评论,获取其ID,然后更新帖子。 当然,您可以在单个请求中发送所有这些任务,这可能比使用猫鼬更有效,但是需要完成的工作类型是相同的。

关于第二个问题:

相对于变体A的好处是,例如,您可以获取该帖子,并立即知道它有多少评论,而无需让mongodb遍历可能是数百个文档。

相对于变体B的好处是,由于mongos的文档大小限制为16MB,因此您可以在单个文档(单个帖子)中存储更多的注释引用 ,而不是整个注释。


但是,您所提到的缺点是,维持这种结构效率很低。 我认为,这只是一个展示场景的示例,因此我将做以下事情:我将根据具体情况决定使用什么。

  • 如果该文件将被读了很多,并没有太大的写入这是不太可能长得比16MB大:嵌入子文档。 这样,您可以在单个查询中获取所有数据。

  • 如果您需要引用多个其他文档中的文档,并且您的数据确实必须一致,那么您只能选择引用它。

  • 如果需要从多个其他文档中引用文档, 但是数据一致性不是那么重要并且第一个项目符号的限制适用,那么请嵌入子文档,并编写代码以保持数据一致。

  • 如果您需要从多个其他文档中引用该文档,并且它们被写得很多,但不经常阅读,则最好引用它们,因为这样更易于编码,因为您无需编写同步重复数据的代码。

在这种特定情况下(发布/评论),从孩子那里引用父母(让孩子知道父母_id )可能是一个好主意,因为它比其他方法更容易维护,并且如果文档大于16MB,它们是直接嵌入的。 如果我可以确定的话,文档不会超过16MB,将它们嵌入会更好,因为这样可以更快地查询数据

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM