Kanishka Panamaldeniya
Kanishka Panamaldeniya

Reputation: 17576

How to get updated document back from the findOneAndUpdate method?

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",

Upvotes: 53

Views: 27065

Answers (9)

Zach Smith
Zach Smith

Reputation: 8961

=== 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 !
  }
)

Upvotes: 9

Naveen Venkatesh
Naveen Venkatesh

Reputation: 201

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/)

Upvotes: 20

Ross Sheppard
Ross Sheppard

Reputation: 870

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;
  ...

Upvotes: 3

sareek
sareek

Reputation: 572

This worked for me.

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

Upvotes: 0

Aljohn Yamaro
Aljohn Yamaro

Reputation: 2881

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

Upvotes: 1

yogesh kumar
yogesh kumar

Reputation: 325

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 
                  }      */       
        }
    });

Upvotes: 7

jamesmhaley
jamesmhaley

Reputation: 45459

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);
  }
});

Upvotes: 4

Ossaija Thankgod
Ossaija Thankgod

Reputation: 454

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.

Upvotes: 13

robertklep
robertklep

Reputation: 203359

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.

Upvotes: 127

Related Questions