Below is my code
var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/test');
var Cat = mongoose.model('Cat', {
name: String,
age: {type: Number, default: 20},
create: {type: Date, default: Date.now}
});
Cat.findOneAndUpdate({age: 17}, {$set:{name:"Naomi"}},function(err, doc){
if(err){
console.log("Something wrong when updating data!");
}
console.log(doc);
});
I already have some record in my mongo database and I would like to run this code to update name for which age is 17 and then print result out in the end of code.
However, why I still get same result from console(not the modified name) but when I go to mongo db command line and type "db.cats.find();
". The result came with modified name.
Then I go back to run this code again and the result is modified.
My question is: If the data was modified, then why I still got original data at first time when console.log it.
By default findOneAndUpdate returns the original document. If you want it to return the modified document pass an options object { new: true }
to the function:
Cat.findOneAndUpdate({ age: 17 }, { $set: { name: "Naomi" } }, { new: true }, function(err, doc) {
});
In some scenarios {new: true}
is not working.
Then you can try this.
{'returnNewDocument':true}
So, "findOneAndUpdate" requires an option to return original document. And, the option is:
{returnNewDocument: true}
Ref: https://docs.mongodb.com/manual/reference/method/db.collection.findOneAndUpdate/
{new: true}
Ref: http://mongoosejs.com/docs/api.html#query_Query-findOneAndUpdate
{returnOriginal: false}
Ref: http://mongodb.github.io/node-mongodb-native/3.0/api/Collection.html#findOneAndUpdate
If you want to return the altered document you need to set the option {new:true}
API reference you can use Cat.findOneAndUpdate(conditions, update, options, callback) // executes
Taken by the official Mongoose API http://mongoosejs.com/docs/api.html#findoneandupdate_findOneAndUpdate you can use the following parameters
A.findOneAndUpdate(conditions, update, options, callback) // executes
A.findOneAndUpdate(conditions, update, options) // returns Query
A.findOneAndUpdate(conditions, update, callback) // executes
A.findOneAndUpdate(conditions, update) // returns Query
A.findOneAndUpdate() // returns Query
Another implementation thats is not expressed in the official API page and is what I prefer to use is the Promise
base implementation that allow you to have .catch
where you can deal with all your various error there.
let cat: catInterface = {
name: "Naomi"
};
Cat.findOneAndUpdate({age:17}, cat,{new: true}).then((data) =>{
if(data === null){
throw new Error('Cat Not Found');
}
res.json({ message: 'Cat updated!' })
console.log("New cat data", data);
}).catch( (error) => {
/*
Deal with all your errors here with your preferred error handle middleware / method
*/
res.status(500).json({ message: 'Some Error!' })
console.log(error);
});
For whoever stumbled across this using ES6 / ES7 style with native promises, here is a pattern you can adopt...
const user = { id: 1, name: "Fart Face 3rd"};
const userUpdate = { name: "Pizza Face" };
try {
user = await new Promise( ( resolve, reject ) => {
User.update( { _id: user.id }, userUpdate, { upsert: true, new: true }, ( error, obj ) => {
if( error ) {
console.error( JSON.stringify( error ) );
return reject( error );
}
resolve( obj );
});
})
} catch( error ) { /* set the world on fire */ }
I know, I am already late but let me add my simple and working answer here
const query = {} //your query here
const update = {} //your update in json here
const option = {new: true} //will return updated document
const user = await User.findOneAndUpdate(query , update, option)
For anyone using the Node.js driver instead of Mongoose, you'll want to use {returnOriginal:false}
instead of {new:true}
.
Mongoose maintainer here. You need to set the new
option to true
(or, equivalently, returnOriginal
to false
)
await User.findOneAndUpdate(filter, update, { new: true });
// Equivalent
await User.findOneAndUpdate(filter, update, { returnOriginal: false });
See Mongoose findOneAndUpdate()
docs and this tutorial on updating documents in Mongoose.
This is the updated code for findOneAndUpdate
. It works.
db.collection.findOneAndUpdate(
{ age: 17 },
{ $set: { name: "Naomi" } },
{
returnNewDocument: true
}
)
Below shows the query for mongoose's findOneAndUpdate
. Here new: true
is used to get the updated doc and fields
is used for specific fields to get.
eg. findOneAndUpdate(conditions, update, options, callback)
await User.findOneAndUpdate({
"_id": data.id,
}, { $set: { name: "Amar", designation: "Software Developer" } }, {
new: true,
fields: {
'name': 1,
'designation': 1
}
}).exec();
Source: Stackoverflow.com