没有事务,MongoDB中的多对多更新

时间:2011-02-14 13:24:06

标签: mongodb

我有两个具有多对多关系的集合。我想在两个文档中存储一个链接的ObjectIds数组,以便我可以快速获取文档A并检索所有链接的文档B,反之亦然。

创建此链接需要两个步骤

  1. 将文档A的ObjectId添加到文档B
  2. 将文档B的ObjectId添加到文档A
  3. 观看MongoDB视频后,我发现这是在两个馆藏之间存储多对多关系的推荐方式

    我需要确保两次更新都已完成。在没有交易的情况下,强有力地处理这个至关重要的两步流程的建议方法是什么?

    我可以将这种关系压缩成单个链接集合,优点是单个更新,文档B没有机会错过文档A的链接。缺点是我没有按预期使用MongoDB。但是,因为只有一个更新,所以拥有一个定义多对多关系的链接集合似乎更健壮。

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

    有什么建议吗?感谢

3 个答案:

答案 0 :(得分:5)

@Gareth ,您有多种合法的方法可以做到这一点。所以他们关键的问题是你打算如何查询数据,(例如:需要快速查询的内容

以下是一些方法。

方法#1:“链接”集合

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

优点:

  • 支持原子更新,以便数据不会丢失

缺点:

  • 尝试在集合之间移动时的额外查询

方法#2:在较大的集合中存储较小映射的副本

例如:您有数百万Products,但只有一百Categories。然后,您将Categories存储为每个Product内的数组。

优点:

  • 占地面积最小
  • 只需要一次更新

缺点:

  • 如果你采取“错误的方式”,则需要额外查询

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

(你在暗示什么)

优点:

  • 单个查询访问以在任一集合之间移动

缺点:

  • 潜在的大型索引
  • 需要交易(?)

让我们谈谈“需求交易”。有几种方法可以进行交易,这实际上取决于您需要什么类型的安全性。

  

我是否应该使用安全模式并手动检查之后数据是否进入并再次尝试失败?

你绝对可以做到这一点。你不得不问自己,如果只有一个保存失败会发生什么最糟糕的事情?

方法#4:对更改进行排队

我不知道你是否曾经使用过队列,但如果你有一些余地,你可以建立一个简单的队列,并有不同的工作来更新他们各自的集合。

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

答案 1 :(得分:2)

为什么不创建一个专用集合,将A和B之间的关系保存为专用行/文档,就像在RDBMS中一样。您可以使用一个当然是原子的操作来修改关系表。

答案 2 :(得分:0)

  

我是否应该使用安全模式并手动检查数据后续进入并再次尝试失败?

是的,这是一种方法,但还有另一种方法 - 您可以实施乐观的交易。它有一些开销和限制,但它保证了数据的一致性。我在GitHub页面上写了一个例子和一些解释。