2011-02-14 29 views
9

许多更新MongoDB中我有两个集合了许多一对多的关系。我想在两个文档中存储一个链接的ObjectIds数组,以便我可以将文档A和快速检索所有链接的文档B,反之亦然。许多无需交易

创建这个链接是一个两步过程

  1. 添加文档A的ObjectID到文档B
  2. 添加文件B的ObjectID文件A

看MongoDB的视频,我发现这之后是存储两个集合

我需要确保两个更新是由之间的许多一对多关系的推荐方式。在没有交易的情况下,强健处理这个关键的两步过程的建议方法是什么?

我可以将此关系压缩为单个链接集合,优点是单个更新,没有文档B缺少指向文档A的链接的机会。缺点是我没有真正按照预期使用MongoDB。但是,因为只有一个更新,所以具有定义多对多关系的链接集合似乎更加健壮。

我应该使用安全模式和手动检查数据进去之后,失败再试一次?或者,我应该只在其中一个集合中表示多对多关系,并依靠索引来确保我仍然可以快速获取链接文档?

有什么建议吗?由于

回答

5

@Gareth,你有多个合法的方式来做到这一点。因此他们主要关心的是您计划如何查询数据(即:什么查询需要快速

以下是几种方法。

方法1:在“链接”收集

你可以建立一个只包含集合之间的映射的集合。

优点:

  • 支持原子更新,使数据不丢失

缺点:

    试图收集之间移动时
  • 额外查询

方法2:在大集

小映射的副本保存例如:你有百万Products,但只有一百Categories。然后,您可以将Categories作为数组存储在Product中。

优点:

  • 占用空间最小
  • 只需要一个更新

缺点:

  • 额外的查询,如果你去了 “错误的方式”

方法3:在两个集合所有映射的副本存储

(你所建议)

优点:

  • 单查询访问之间移动任一系列

缺点:

  • 潜在的大指标
  • 需要交易

让我们来谈谈 “需要交易”(?)。有几种方法可以进行交易,这取决于您需要的安全类型。

我应该使用安全模式和手动检查数据进去之后,失败再试一次?

你绝对可以做到这一点。你将不得不问自己,如果只有其中一次保存失败会发生什么情况?

方法#4:排队的改变

我不知道,如果你曾经与队列的工作,但如果你有一些回旋余地,你可以建立一个简单的队列,并有不同的工作是更新各自的收藏。

这是一个更先进的解决方案。我倾向于与#2或#3一起去。

2

你为什么不建立一个专门的回收控股作为专用的行/文档A和B之间的关系是一个将在RDBMS做到这一点。你可以用一个当然是原子的操作来修改关系表。

+0

谢谢,我在我的问题中考虑了这种方法,但在视频中,我看到这并不推荐作为MongoDB的方式 – 2011-02-14 13:39:59

+1

视频是一个授权信息来源吗? MongoDB只为单一操作提供原子性。如果事务支持很重要:或者不要使用MongoDB,或按照描述使用MongoDB。你不能拥有一切。 – 2011-02-14 13:57:13

0

我应该使用安全模式并手动检查之后进入的数据,并在失败时再试一次?

这是一种方法,但有一个其他 - 你可以实现一个乐观事务。它有一些开销和限制,但它保证了数据的一致性。我在GitHub页面上写了一个例子和一些解释。