下面是我的代码
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}
似乎不适用于 updateOne
,将 updateOne
替换为 findOneAndUpdate
及其工作
为什么会发生这种情况?
默认是返回原始的、未更改的文档。如果您希望返回新的、更新的文档,您必须传递一个附加参数:一个将 new
属性设置为 true
的对象。
Query#findOneAndUpdate Model.findOneAndUpdate(conditions, update, options, (error, doc) => { // error: 发生的任何错误 // doc: 如果 `new: false` 应用更新前的文档,如果更新后应用`new = true` });可用选项 new: bool - 如果为真,则返回修改后的文档而不是原始文档。默认为 false(在 4.0 中更改)
解决方案
如果您想要 doc
变量中的更新结果,则传递 {new: true}
:
// V--- THIS WAS ADDED
Cat.findOneAndUpdate({age: 17}, {$set:{name:"Naomi"}}, {new: true}, (err, doc) => {
if (err) {
console.log("Something wrong when updating data!");
}
console.log(doc);
});
对于使用 Node.js 驱动程序而不是 Mongoose 的任何人,您需要使用 {returnOriginal:false}
而不是 {new:true}
。
2021 - Mongodb ^4.2.0 更新
{ returnDocument: 'after' }
"mongodb": "^3.6.9"
,而 { returnOriginal:false }
已弃用。请改用 { returnDocument: 'after' }
。
{ returnOriginal: false }
已弃用。但是由于某种原因,我无法让它发挥作用,而使用该建议它可以按预期工作。
因此,“findOneAndUpdate”需要一个选项来返回原始文档。而且,选项是:
MongoDB外壳
{returnNewDocument: true}
参考:https://docs.mongodb.com/manual/reference/method/db.collection.findOneAndUpdate/
猫鼬
{new: true}
参考:http://mongoosejs.com/docs/api.html#query_Query-findOneAndUpdate
Node.js MongoDB 驱动程序 API:
{returnOriginal: false}
2021 - Mongodb ^4.2.0 更新
{ returnDocument: 'after' }
参考:http://mongodb.github.io/node-mongodb-native/3.0/api/Collection.html#findOneAndUpdate
'returnDocument' => FindOneAndUpdate::RETURN_DOCUMENT_AFTER
默认情况下 findOneAndUpdate 返回原始文档。如果您希望它返回修改后的文档,请将选项对象 { new: true }
传递给函数:
Cat.findOneAndUpdate({ age: 17 }, { $set: { name: "Naomi" } }, { new: true }, function(err, doc) {
});
_id
为空?
对于使用带有原生承诺的 ES6 / ES7 风格偶然发现这一点的人,这里有一个你可以采用的模式......
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 */ }
猫鼬维护者在这里。您需要将 new
选项设置为 true
(或者,等效地,将 returnOriginal
设置为 false
)
await User.findOneAndUpdate(filter, update, { new: true });
// Equivalent
await User.findOneAndUpdate(filter, update, { returnOriginal: false });
请参阅 Mongoose findOneAndUpdate()
docs 和 this tutorial on updating documents in Mongoose。
这是 findOneAndUpdate
的更新代码。有用。
db.collection.findOneAndUpdate(
{ age: 17 },
{ $set: { name: "Naomi" } },
{
returnNewDocument: true
}
)
如果您想返回更改后的文档,您需要设置选项 {new:true}
API 参考,您可以使用 Cat.findOneAndUpdate(conditions, update, options, callback) // executes
由官方 Mongoose API http://mongoosejs.com/docs/api.html#findoneandupdate_findOneAndUpdate 采用,您可以使用以下参数
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
另一个未在官方 API 页面中表达的实现,我更喜欢使用的是 Promise
基本实现,它允许您拥有 .catch
,您可以在那里处理所有各种错误。
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);
});
我知道,我已经迟到了,但让我在这里添加我简单而有效的答案
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)
下面显示了 mongoose 的 findOneAndUpdate
的查询。这里new: true
用于获取更新的文档,fields
用于获取特定字段。
例如。 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();
2021 - Mongodb ^4.2.0 更新
这适用于 mongodb 节点驱动程序,而不是 mongoose。
如果您使用“collection.findOneAndUpdate”搜索和更新,最新版本的 Mongodb 节点驱动程序似乎使用以下语法:
.findOneAndUpdate(query, update, { returnDocument: 'after' | 'before' })
搜索时我自己在这里找不到答案,所以发布这个以防其他人处于同样的情况。
在某些情况下,{new: true}
不起作用。然后你可以试试这个。
{'returnNewDocument':true}
export function newDocumentOnUpdatePlugin(schema) {
schema.pre(
['update', 'findOneAndUpdate', 'updateOne', 'updateMany'],
function (next) {
this.setOptions({ new: true });
next();
},
);
}
如果有人在整个应用程序中需要此功能并希望避免重复,我已经创建了这个插件。只需将其用作 global plugin
不定期副业成功案例分享
_id
为空,所以它不是真正的新文档。{ returnOriginal: false }