Mongoose: findOneAndUpdate не возвращает обновленный документ

106

Ниже мой код

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

У меня уже есть запись в моей базе данных mongo, и я бы хотел запустить этот код для обновления имени, для которого возраст равен 17, а затем распечатать результат в конце кода.

Однако, почему я все еще получаю тот же результат от консоли (не изменяю имя), но когда я иду в командную строку mongo db и набираю "db.cats.find();". Результат был изменен.

Затем я возвращаюсь, чтобы снова запустить этот код, и результат будет изменен.

Мой вопрос: данные были изменены, но почему я все же получил исходные данные в первый раз, когда console.log его.

Теги:
mongoose

5 ответов

211
Лучший ответ

По умолчанию используется возврат неизмененного документа. Если вы хотите, чтобы новый, обновленный документ возвращался, вам нужно передать дополнительный аргумент: объект с свойством new, установленным в true.

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

ЗапроС# 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`
}

Доступные параметры

new: bool - если true, верните измененный документ, а не оригинал. по умолчанию - false (изменено в 4.0)

Итак, если вы хотите обновленный результат в переменной doc:

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

    console.log(doc);
});
  • 8
    Похоже, это не работает для меня, он по-прежнему возвращает старый документ с новым: true.
  • 0
    @PDN Какая у вас версия mongoose / mongo? Это может мешать, как это работает.
Показать ещё 11 комментариев
25

По умолчанию findOneAndUpdate возвращает исходный документ. Если вы хотите, чтобы он возвратил измененный документ, передайте объект параметров { new: true } в функцию:

Cat.findOneAndUpdate({ age: 17 }, { $set: { name: "Naomi" } }, { new: true }, function(err, doc) {

});
  • 0
    почему _id нулевой?
18

Для тех, кто использует драйвер Node.js вместо Mongoose, вы захотите использовать {returnOriginal:false} вместо {new:true}.

  • 1
    Спасибо! Это работает для меня версия узла mongodb 2.2.27
  • 0
    Это все еще не работает для меня :(
10

Для тех, кто наткнулся на это, используя стиль ES6/ES7 с родным promises, вот шаблон, который вы можете принять...

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 */ }
  • 13
    Mongoose вернет обещание, если вы не предоставите функцию обратного вызова. Нет необходимости создавать свое собственное обещание!
  • 1
    @joeytwiddle Mongoose не вернет Обещание, если вы не предоставите обратный вызов. Вместо этого он возвращает объект Query, который предоставляет только небольшое подмножество API Promise. Это в соответствии с документацией Mongoose.
2

Это обновленный код для findOneAndUpdate. Он работает.

db.collection.findOneAndUpdate(    
  { age: 17 },      
  { $set: { name: "Naomi" } },      
  {
     returnNewDocument: true
  }    
)

Ещё вопросы

Сообщество Overcoder
Наверх
Меню