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 modify the name) but when I go to mongo db command line and type "db.cats.find();". The result was modify.

Then I go back to run this code again and the result is modified.

My question is: the data was modify but why I still got original data at first time when console.log it.

share|improve this question
up vote 113 down vote accepted

The default is to return the unaltered document. If you want the new, updated document to be returned you have to pass an additional argument named new with the value true.

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

Query#findOneAndUpdate

function(error, doc) {
  // error: any errors that occurred
  // doc: the document before updates are applied if `new: false`, or after updates if `new = true`
}

Available options

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

So, if you want the updated result in the doc variable:

Cat.findOneAndUpdate({age: 17}, {$set:{name:"Naomi"}}, {new: true}, function(err, doc){
    if(err){
        console.log("Something wrong when updating data!");
    }

    console.log(doc);
});
share|improve this answer
2  
This appears to be broken for me, it still returns the old document with new: true. – PDN Apr 21 '16 at 7:57
    
@PDN What version of mongoose/mongo do you have? That might be messing with how it works. – PawnStar May 11 '16 at 20:57
24  
This is the most intuitive default I've seen recently. /sarcasm – Michael Fulton Jul 4 '16 at 22:00
1  
makes sense to me since you already have access to the new document – danday74 Jul 23 '16 at 5:40
    
it worked for me, I'm using moogose version 4.6.3, thanks – cesar andavisa Oct 20 '16 at 12:16

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

});
share|improve this answer
    
why is _id null? – chovy Jan 16 at 4:59

For whoever stumbled across this using ES6 / ES7 style with native promises, here is a pattern you can adopt...

var user = { id: 1, name: "Fart Face 3rd"};
var userUpdate = { name: "Pizza Face" };

try {
    user = await new Promise( function( resolve, reject ) {
        User.update( { _id: user.id }, userUpdate, { upsert: true, new: true }, function( error, obj ) {
            if( error ) {
                console.error( JSON.stringify( error ) );
                return reject( error );
            }

            resolve( obj );
        });
    })
} catch( error ) { /* set the world on fire */ }
share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.