我还没有准备好放手,这就是为什么我重新考虑问题并编辑Q(以下原始内容)的原因。

我正在使用mongoDB进行周末项目,这需要数据库中的某些关系,这就是苦难的全部原因:

我有三个收藏:

Users
Lists
Texts

用户可以具有文本和列表-列出“包含”文本。文本可以在多个列表中。

我决定使用单独的集合(而不是嵌入),因为子文档并不总是出现在其父文档的上下文中(例如,所有文本,没有出现在列表中)。

因此,需要做的是准确地引用属于某些列表的文本。列表和文本可以是无限制的,尽管列表相比会更少。

与我最初想到的相反,我还可以将引用放在每个单独的文本文档中,而不是放在列表文档中的所有text-id中。实际上,这会有所作为,因为我可以避免使用一个查询来查找列表中的每个代码段。甚至可以索引该引用。
var TextSchema = new Schema({
      _id: Number,
      name: String,
      inListID: { type : Array , "default" : [] },
      [...]

文本将出现在许多列表中的情况也很少出现,因此该数组不会真正爆炸。不过,问题仍然存在,这是否有可能扩大规模或实际上是使用mongoDB实现的更好方法?限制文本可以(可能)包含的列表数量是否有帮助?有几个人的秘诀吗?很多关系吗?

引用完成了哪些项目以及如何实现的项目,甚至会很棒(很少:很多关系)。我不敢相信只要需要一些关系,每个人都会回避mongo DB。



原始问题

到目前为止,我将其分解为两个问题:
1)假设一个列表由5个文本组成。如何引用列表中包含的文本?只需打开一个数组并将文本的_id存储在其中?好像这些数组可能长到月球然后再放回去,从而降低了应用程序的运行速度?另一方面,文本需要没有列表,因此嵌入并不是真正的选择。如果我想获取包含100个文本的列表的所有文本,该怎么办?听起来像两个查询和一个包含100个字段的数组:-/。那么,这种引用正确方法的方式呢?
var ListSchema = new Schema({
  _id: Number,
  name: String,
  textids: { type : Array , "default" : [] },
  [...]

问题2)如果删除了文本,我发现使用这种方法正在清理引用。它的引用仍将存在于包含文本的每个列表中,并且我不想遍历所有列表以清除那些无效的引用。还是我呢?有解决这个问题的聪明方法吗?仅使文本成为引用(在它们的列表中)就可以解决问题,因此这不是一个选择。

我想我不是第一个遇到这种问题的人,但我也找不到关于如何“正确”解决问题的明确答案。

我也对这种引用的最佳实践的一般想法感兴趣(很多对很多?),尤其是可伸缩性/性能。

最佳答案

关系通常不是什么大问题,尽管某些涉及关系的操作可能是问题。这在很大程度上取决于您要解决的问题,并且在很大程度上取决于结果集的基数和键的选择性。

我写了a simple testbed,它按照典型的长尾分布生成数据以供使用。事实证明,MongoDB在关系方面通常比人们认为的要好。

毕竟,关系数据库只有三个区别:

  • 外键约束:您必须自己管理这些约束,因此存在链接无效的风险
  • 事务隔离:由于没有多文档事务,因此即使代码正确(从某种意义上说,它从不尝试创建无效链接),也有可能创建无效的外键约束,而只是在运行时中断。另外,很难检查无效链接,因为您可能会观察到竞争状况
  • 联接:MongoDB不支持联接,尽管使用 $in 的手动子查询确实可以将$in-子句中的数千个项目很好地扩展,只要对引用值进行了索引,当然

  • 如果您需要执行大型联接,即,如果您的查询是真正的关系型,并且您需要相应地联接大量数据,则MongoDB可能不是一个很好的选择。但是,关系数据库中所需的许多联接并不是真正的关系,它们是必需的,因为您必须将对象拆分为多个表,例如,因为它包含一个列表。

    “真实的”关系查询的一个示例可以是“找到我所有购买了在6月份营业额排名最高的客户购买了4颗星评论的产品的客户”。除非您有一个专门为支持此查询而构建的非常专业的架构,否则您很可能需要查找所有订单,将其按客户ID分组,获取前n个结果,并使用$in来查询等级,然后使用另一个$in查找实际客户。不过,如果您可以将自己限制在最高水平(例如6月的1万名客户),则这是三个往返行程和一些快速的$in查询。

    只要您的查询受RAM中的索引支持并且网络不完全拥塞,则在典型的云硬件上,此范围可能会在10到30毫秒之间。在此示例中,如果数据太稀疏,情况就会变得困惑,即,前10k用户几乎没有写过4星以上的评论,这将迫使您编写足够聪明的程序逻辑以保持迭代的第一步,而这既复杂又缓慢,但是如果那是一个如此重要的场景,那么总有可能存在更适合的数据结构。

    关于node.js - 不同集合中文档之间的Mongo DB关系,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/30459764/

    10-16 17:57