Ниже мой код
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 его.
По умолчанию используется возврат неизмененного документа. Если вы хотите, чтобы новый, обновленный документ возвращался, вам нужно передать дополнительный аргумент: объект с свойством 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);
});
По умолчанию findOneAndUpdate возвращает исходный документ. Если вы хотите, чтобы он возвратил измененный документ, передайте объект параметров { new: true }
в функцию:
Cat.findOneAndUpdate({ age: 17 }, { $set: { name: "Naomi" } }, { new: true }, function(err, doc) {
});
_id
нулевой?
Для тех, кто использует драйвер Node.js вместо Mongoose, вы захотите использовать {returnOriginal:false}
вместо {new:true}
.
Для тех, кто наткнулся на это, используя стиль 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 */ }
Это обновленный код для findOneAndUpdate
. Он работает.
db.collection.findOneAndUpdate(
{ age: 17 },
{ $set: { name: "Naomi" } },
{
returnNewDocument: true
}
)