MongoDB 和 Mongoose:文档引用 ID 的嵌套数组 [英] MongoDB and Mongoose: Nested Array of Document Reference IDs

查看:59
本文介绍了MongoDB 和 Mongoose:文档引用 ID 的嵌套数组的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在深入研究 MongoDB,并发现了一种特别有趣的模式来存储文档之间的关系.此模式涉及包含引用子文档的 id 数组的父文档,如下所示:

I have been diving into a study of MongoDB and came across a particularly interesting pattern in which to store relationships between documents. This pattern involves the parent document containing an array of ids referencing the child document as follows:

//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(更新帖子)和新评论,这对于使用普通关系数据库时发送的请求来说都是常见的.当需要将新评论写入数据库时​​,问题就会出现.我必须做 2 次写入和 1 次读取,而不是像在普通关系数据库中那样进行一次 db 写入.第一次写入以插入新评论并检索 _id.然后读取以通过随请求发送的 Post _id 检索 Post,以便我可以将新的 Comment _id 推送到嵌套引用数组.最后,最后一次写入将 Post 更新回数据库.

This all seems fine and dandy until I go to send a request from the front end to create a new comment. The request has to contain the Post _id (to update the post) and the new Comment, which are both common to a request one would send when using a normal relational database. The issue appears when it comes time to write the new Comment to the database. Instead of one db write, like you would do in a normal relational database, I have to do 2 writes AND 1 read. The first write to insert the new Comment and retrieve the _id. Then a read to retrieve the Post by the Post _id sent with the request so I can push the new Comment _id to the nested reference array. Finally, a last write to update the Post back into the database.

这看起来效率极低.我的问题有两个:

This seems extremely inefficient. My question is two-fold:

  1. 是否有更好/更有效的方法来处理这种关系模式(父级包含一组子引用 ID)?

  1. Is there a better/more efficient way to handle this relationship pattern (parent containing an array of child reference ids)?

如果不是,与 A) 将父 _id 存储在类似于传统外键的子属性中,或 B) 利用 MongoDB 文档和存储相比,使用此模式有什么好处一个 Comments 数组,而不是一个 Comments 的引用 ID 数组.

If not, what would be the benefit of using this pattern as opposed to A) storing the parent _id in a property on the child similar to a traditional foreign key, or B) taking advantage of MongoDB documents and storing an array of the Comments as opposed to an array of reference ids to the Comments.

提前感谢您的见解!

推荐答案

关于你的第一个问题:

您特别要求一种更好的方法来处理存储在父级中的子 ID.我很确定没有更好的方法来处理这个问题,如果它必须是这种模式.

You specifically ask for a better way to work with child-ids that are stored in the parent. I'm pretty sure that there is no better way to deal with this, if it has to be this pattern.

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

But this problem also exist in relational databases. If you want to save your post in a relational database (using that pattern), you also have to first create the comment, get its ID and then update the post. Granted, you can send all these tasks in a single request, which is probably more efficient than using mongoose, but the type of work that needs to be done is the same.

关于你的第二个问题:

变体 A 的好处是,例如,您可以获取帖子,并立即知道它有多少评论,而无需要求 mongodb 浏览可能的成百份文件.

The benefit over variant A is, that you can for example get the post, and instantly know how many comments it has, without asking the mongodb to go through probably hundrets of documents.

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

The benefit over variant B is, that you can store more references to comments in a single document (a single post), than whole comments, because of mongos 16MB document-size-limit.

然而,缺点是您提到的那个,即维持该结构效率低下.我认为这只是展示场景的一个例子,所以这是我要做的:我会根据具体情况决定使用什么.

The Downside however is the one you mentioned, that it's inefficient to maintain that structure. I take it, that this is only an example to showcase the scenario, so here is what i would do: I would decide on a case by case basis what to use.

  • 如果文档会被大量阅读,而不会被写入太多,并且它不太可能超过 16MB:嵌入子文档.这样您就可以在一个查询中获取所有数据.

  • If the document will be read a lot, and not much written to, AND it is unlikely to grow larger than 16MB: Embed the sub-document. this way you can get all the data in a single query.

如果您需要从多个其他文档并且引用该文档,并且您的数据确实必须保持一致,那么您别无选择,只能引用它.

If you need to reference the document from multiple other documents AND your data really must be consistent, then you have no choice but to reference it.

如果您需要从多个其他文档中引用该文档数据一致性不是那么重要AND限制从第一个要点开始应用,然后嵌入子文档,并编写代码以保持数据一致.

If you need to reference the document from multiple other documents BUT data-consitency is not that super important AND the restrictions from the first bulletpoint apply, then embed the sub-documents, and write code to keep your data consistent.

如果您需要从多个其他文档中引用该文档,并且它们被写入了很多,但不经常阅读,您可能最好参考它们,因为这更容易编码,因为您不需要编写代码来同步重复数据.

If you need to reference the document from multiple other documents, and they are written to a lot, but not read that often, you're probably better off referencing them, as this is easier to code, because you don't need to write code to sync duplicate data.

在这种特定情况下(发布/评论)从孩子引用父母(让孩子知道父母_id)可能是个好主意,因为它比其他方式更容易维护,如果直接嵌入,文档可能会增长到 16MB 以上.如果我确定知道文档不会超过 16MB,嵌入它们会更好,因为这样查询数据会更快

In this specific case (post/comment) referencing the parent from the child (letting the child know the parents _id) is probably a good idea, because it's easier to maintain than the other way around, and the document might grow larger than 16MB if they were embedded directly. If i'd know for sure, that the document would NOT larger than over 16MB, embedding them would be better, because its faster to query the data that way

这篇关于MongoDB 和 Mongoose:文档引用 ID 的嵌套数组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆