2014-03-24 52 views
1

可以說我有一個mongoDB數據庫,在該數據庫中創建屬於同時將文檔和用戶存儲在數據庫中的用戶的文檔。mongodb/mongoose,在更改兩個文檔時如何確保數據一致

讓我們進一步說,用戶對象包含對文檔的引用。

創建一個新文檔可能看起來像這樣。

exports.create = function (req, res, next) { 

    //make a new document 
    var newDoc = new Document({ 
    title: req.body.title, 
    content: req.body.content, 
    }); 
    User.findById(req.user._id, function (err, user) { 
    if (err) 
     return res.send(400); 
    user.documents.push(newDocument._id); 
    user.save(function(err){ 
     if (err) 
     return res.json(400, err); 
     newDoc.save(function(err) { 
     if (err) 
      return res.json(400, err); //<--- What if you have an error here?? 
     return res.json(200, {document:'successfully created'}); 
     }); 
    }); 
    }); 
}; 

如果你有在最後,如果(ERR)的錯誤,你會加入到一個新的文檔的引用給用戶,但文件不會被創建。

當然這是一個非常簡單的例子。由於大量的文檔相互引用,它會變得複雜得多。在Mongo/Mongoose中處理這個問題的最簡單方法是什麼?

+0

您似乎在尋找事務和回滾,這是不存在的。如果你真的**必須**維護單獨的集合,那麼至少要先嚐試「保存」引用的文檔**。然後用參考更新「主」文件。任何「回滾」都必須手動完成。 –

回答

2

它看起來像您的用戶文檔關係是一對多。您當前要添加新文檔的操作需要寫入兩個集合。

MongoDB不提供任何事務(可能將來),所以你唯一的選擇是從文件數組中刪除文件id,如果文件保存失敗。但它需要另一次寫入,也可能會失敗。

要更原子化,並在一次寫入中完成所有操作,可以將userId字段添加到Document集合中,並從User集合中刪除decuments數組。

還在Document集合中的userId上創建一個索引。現在您的文檔引用用戶並創建新文檔只需要一次寫入。如果寫入失敗,則數據庫中的任何更改都不會保持一致。

+0

因此,在查找所有用戶的文檔時,Atomicity的折衷必須執行查詢。 – honkskillet

+0

您在查找用戶文檔時仍然需要執行查詢,因爲您只有_id。索引的userId字段使查詢閃電般快速。您也可以將文檔直接嵌入到用戶中,但很可能文檔增長超過16MB。 – chatoooo

+0

啊。我提出的示例代碼與我的真實代碼相比簡單一些。在我的應用程序中,用戶和文檔相互引用。 – honkskillet

相關問題