How to get updated document back from the findOneAndUpdate method?

Javascriptnode.jsMongodbExpress

Javascript Problem Overview


I am using MongoDB with node js , i used npm install mongodb

I want to update an existing document and return the updated document , the document is updated correctly . but it returns the old document means the original document before update . i have used the returnNewDocument:true parameter but no use .

            var filter = {
                '_id': object_id
            },
            update = {
                $set: { "status" : data["status"] },
                $push: {
                    "statusHistory": {
                        $each: [{ status:data["status"],statusChangedTime:data["statusChangedTime"],comment:data["comment"]}],
                        $position:0,
                    }
                },
            }
            ,options = {
                //upsert: false,
                //multi: false,
                returnNewDocument: true
            };

            col.findOneAndUpdate(filter, update, options,function(err, res) {
                if (err) {

                    console.log(err);
                }else {

                    console.log(res);
                }
            });

the response is

{ lastErrorObject: { updatedExisting: true, n: 1 },
  value: 
   { 
//original document
   },     
  ok: 1 }

when i directly go to mongoDB through terminal and try

db.MyCollection.find().pretty();

the document is updated correctly, it just returns the original instead of updated one.

Stuck here for 2 hours, any help is appreciated

in package.json

"mongodb": "^2.1.4",

Javascript Solutions


Solution 1 - Javascript

The Node.js driver documentation doesn't mention a returnNewDocument option for findOneAndUpdate() (which is an option for the MongoDB shell command with the same name).

Instead, it mentions an option called returnOriginal, which defaults to true. Try using that option, setting it to false to return the updated document instead of the original.

Solution 2 - Javascript

To get the updated document after performing the update operation we need to use the option "returnDocument" : "after" along with "returnOriginal" : false.

As per the latest mongodb node driver v3.6 documentation, the usage of returnOriginal is deprecated. But when I try only including "returnDocument" : 'after' without "returnOriginal":false its returning the original record instead of the updated record. Using them both is giving the desired output of updated record instead of the original record. (source : http://mongodb.github.io/node-mongodb-native/3.6/api/Collection.html#findOneAndUpdate)

The option "returnNewDocument" : true is a mongo shell option and may not work in the node driver as per the official mongodb documentation ( mentioned here https://docs.mongodb.com/manual/reference/method/db.collection.findOneAndUpdate/)

Solution 3 - Javascript

If you are seeing this latest 2018, neither returnNewDocument:true nor returnOriginal: false, works. You have to instead set a property called new to true as in {.., new: true} in the option object for your query.

Solution 4 - Javascript

The NodeJS MongoDB driver has different arguments compared to the native MongoDB shell for the command findOneAndUpdate(). If you are using "mongodb": "^2.1.4" then use

> returnOriginal: false

instead

> returnNewDocument: true

.

Let's see below code:

db.collection('user_setting').findOneAndUpdate({user_id: data.user_id}, {$set: data}, {projection: dbConfig.userSetting, returnOriginal: false}, function (err, res) {
        if (err) {
            callback({'error': 1, 'message': 'Internal server error! ' + err, 'data': null, 'status': 500});
        }   else {
                 console.log(res);
                /* { lastErrorObject: { updatedExisting: true, n: 1 },
                      value: 
                           { user_id: 1,
                             notification_alert: 1,
                             notification_sound: 1,
                             user_setting_id: 2 
                            },
                       ok: 1 
                  }      */       
        }
    });

Solution 5 - Javascript

=== Aug 2021

With the release of v4 of the node.js client, it seems the old solution of returnOriginal: false (which was awful anyway) is no longer the correct answer.

To see the list of available options for the node.js findOneAndUpdate method: https://mongodb.github.io/node-mongodb-native/4.0/interfaces/findoneandupdateoptions.html

But in short, this should work:

const doc = await <Collection>.findOneAndUpdate(
  { ... search },
  {
    $set: {
      field1: 'value 1',
      field2: ['value 2'],
      etc.
    },
  },
  {
    upsert: true,
    returnDocument: 'after', // this is new !
  }
)

Solution 6 - Javascript

If anyone else ran into this issue when using { returnOriginal: false } within a Mongoose setup:

Mongoose uses { new: true } instead of { returnOriginal: false }.

The feature is referenced here: Mongoose: findOneAndUpdate doesn't return updated document and within the Mongoose docs:

>Options:

>new: bool - if true, return the modified document rather than the original. defaults to false (changed in 4.0)

So when using findOneAndUpdate add new: true to the method options:

...

const options = {
  new: true
};

col.findOneAndUpdate(filter, update, options, function (err, res) {
  if (err) {
    console.log(err);
  } else {
    console.log(res);
  }
});

Solution 7 - Javascript

According to the actual source code and type definition for 4.0+, the new property is now new. Set it true to return the modified result.

interface QueryFindOneAndUpdateOptions extends QueryFindOneAndRemoveOptions {
  /** if true, return the modified document rather than the original. defaults to false (changed in 4.0) */
  new?: boolean;
  ...

Solution 8 - Javascript

I am using mongoose: 5.8.9

with these lines below

const option = { new: true }
const account = await Account.findOneAndUpdate(filter, update, option)

and this is working

Solution 9 - Javascript

This worked for me.

req.db.collection(collectionName).findOneAndUpdate(
          { _id : commentById._id }, // matching parameters
           updateOpts, //updating parameters
          {returnOriginal: false}  //don't use **returnNewDocument**
         );

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionKanishka PanamaldeniyaView Question on Stackoverflow
Solution 1 - JavascriptrobertklepView Answer on Stackoverflow
Solution 2 - JavascriptNaveen VenkateshView Answer on Stackoverflow
Solution 3 - JavascriptOssaija ThankgodView Answer on Stackoverflow
Solution 4 - Javascriptyogesh kumarView Answer on Stackoverflow
Solution 5 - JavascriptZach SmithView Answer on Stackoverflow
Solution 6 - JavascriptjamesmhaleyView Answer on Stackoverflow
Solution 7 - JavascriptRoss SheppardView Answer on Stackoverflow
Solution 8 - JavascriptAljohn YamaroView Answer on Stackoverflow
Solution 9 - JavascriptsareekView Answer on Stackoverflow