Reputation: 17576
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
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
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
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
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
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
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
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
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
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