Reputation: 3137
Lets say I have a mongoDB database where I create a document that belongs to a user where both documents and users are stored in the DB.
Let's further say that the user object contains a reference to the document.
Creating a new document might looks something like this.
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'});
});
});
});
};
If you have an error at the last if(err), you will have added a reference to a new document to the user but the document will not have been created.
And of course this is a very simple case. It can get much more complicated with numerous documents referencing each other. What is the cleanest way of handling this in Mongo/Mongoose?
Upvotes: 4
Views: 2108
Reputation: 3137
While pondering my question, I ran across this... a discussion of two phase commits with MongoDB. http://docs.mongodb.org/manual/tutorial/perform-two-phase-commits/
It's not the answer I'll accept, but I think it is relevant.
Upvotes: 1
Reputation: 326
It looks like your User Document relation is One-to-Many. Your current operation to add new document requires writes into two collections.
MongoDB does not provide any transactions (maybe it will in future), so your only option is to remove document id from users documents array, if document save fails. But it will require another write which may also fail.
To be more atomic and make all done in one write, you can add userId field into Document collection and remove decuments array from User collection.
Also create an index on userId in Document collection. Now your document references user and creating new document requires only one write. If this write fails nothing changes in your database and consistency is kept.
Upvotes: 5