10

Is there a nice way of either saving, or updating a document in mongoose? Something like what I'm after below

 let campaign = new Campaign({
        title: req.body.title,
        market: req.body.market,
        logo: req.body.logo,
        additional_question_information: question,
        status: status
    });

 campaign.saveOrUpdate().then(function() { ... }

Thanks for the help all

Ollie
  • 1,104
  • 7
  • 24
  • 45
  • What is your question? What you are doing is correct. – itsundefined May 31 '17 at 14:34
  • 1
    Sorry, I wasn't clear at all. I want to save a document if it doesn't exist, OR update a preexisting one with the new data. Is there a method to do that in mongoose? Seems like it'd be nice – Ollie May 31 '17 at 14:44
  • 1
    Possible duplicate of [How do I update/upsert a document in Mongoose?](https://stackoverflow.com/questions/7267102/how-do-i-update-upsert-a-document-in-mongoose?) – Neil Lunn May 31 '17 at 23:23
  • See [Insert-or-Update with MongoDB and Mongoose](https://silvantroxler.ch/2016/insert-or-update-with-mongodb-and-mongoose/). – str Jun 02 '17 at 08:16
  • Possible duplicate of [How do I update/upsert a document in Mongoose?](https://stackoverflow.com/questions/7267102/how-do-i-update-upsert-a-document-in-mongoose) – str Jun 02 '17 at 08:18

2 Answers2

16

I think what you're looking for is called an 'upsert'.

You can do this by using findOneAndUpdate and passing the { upsert: true } option, something like the below example:

let campaign = new Campaign({
        title: req.body.title,
        market: req.body.market,
        logo: req.body.logo,
        additional_question_information: question,
        status: status
    });

Campaign.findOneAndUpdate({
    _id: mongoose.Types.ObjectId('CAMPAIGN ID TO SEARCH FOR')
}, campaign, { upsert: true }, function(err, res) {
    // Deal with the response data/error
});

The first parameter to findOneAndUpdate is the query used to see if you're saving a new document or updating an existing one. If you want to return the modified document in the response data then you can also add the { new: true } option.

Documentation here for findOneAndUpdate: http://mongoosejs.com/docs/api.html#model_Model.findOneAndUpdate

CD-jS
  • 1,125
  • 1
  • 15
  • 32
  • 1
    I think the braces { } around the campaign object in the .findOneAndUpdate call should not actually be there. – stephent Nov 30 '17 at 20:31
  • Good catch! Edited the answer. – CD-jS Dec 01 '17 at 11:27
  • 2
    Just an FYI doing a `findOneAndUpdate` does NOT set off any middlewares revolving around `save`. Reference: http://mongoosejs.com/docs/middleware.html#notes – TheNastyOne Dec 17 '17 at 19:21
0

You can use the MongoDB's findAndModify function. In mongoose this is natively supported by calling findOneAndUpdate(). Here is the documentation for it. http://mongoosejs.com/docs/api.html#query_Query-findOneAndUpdate Notice that in the third argument it awaits for an object to be passed with options. You want to use { upsert : true } in there to create a new document if one does not exist.

itsundefined
  • 1,409
  • 2
  • 12
  • 32