2011-02-14 45 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頁面上寫了一個例子和一些解釋。