zhuchun
zhuchun

Reputation: 313

How to use mongoose to save multiple documents?

I have 2 models here user and blog. So when an user write a blog, my router invoke them like this.

Promise.all([
                    node.save(),
                    user.save()
                ]).then(function (values) {                    
                    //do something
                }).catch(function (err) {
                    //print error
                })

As you may notice immediately, there's no guarantee for save(). Either of them could fails and no rollback for the rest. How can I make sure both of them are saved or rollbacked? Some people suggest to put blogs collection inside users so everything is in a single document, but that's hard to do blog ranking, isn't it? I'm also not sure if it's really a good practice that putting all things together in MongoDB. if documents are large, will it cause performance issues(say requests/second)?

Thanks.

Upvotes: 1

Views: 3859

Answers (1)

Robert Moskal
Robert Moskal

Reputation: 22553

You can't use Promise.all, you'll have to chain your promises individually.

node.save().then(user.save).then(function(){//do something else});

You'll also have to work a little harder to get all the entities in an array like you get with Promise.all. But do you really need that? You have access to the user and the node entities already.

The classic way to do this would be using async and series:

async.series({

     node: node.save,
     user:user.save
}, function(err, res){
        // res is now equal to: {node:node, user:user}
   });

Most people simply don't bother with two phase commits using Mongo. If you really need this, perhaps you are using the wrong tool.

If the node save fails, the user won't be saved. If you can't save the node without the user being saved, reverse the order order of operations. If both MUST be updated for either to be, I'd probably rethink my data model.

If you really need a two phase commit, you need to reinvent that particular wheel. There's a recipe for doing it in the documentation. Or you can try one of the mongoose plugins that purport to do it.

Upvotes: 3

Related Questions