Mongoose:findOneAndUpdate 不返回更新的文档
Posted
技术标签:
【中文标题】Mongoose:findOneAndUpdate 不返回更新的文档【英文标题】:Mongoose: findOneAndUpdate doesn't return updated document 【发布时间】:2019-04-10 09:11:02 【问题描述】:下面是我的代码
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
及其工作
【参考方案1】:
为什么会这样?
默认是返回原始的、未更改的文档。如果您希望返回新的、更新的文档,您必须传递一个附加参数:new
属性设置为 true
的对象。
来自mongoose docs:
查询#findOneAndUpdate
Model.findOneAndUpdate(conditions, update, options, (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
变量中的更新结果,请传递 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);
);
【讨论】:
这对我来说似乎坏了,它仍然返回旧文档,新:true。 对我来说很有意义,因为您已经可以访问新文档 它对我有用,我使用的是 moogose 版本 4.6.3,谢谢 我得到了新文档,但_id
为空,所以它不是真正的新文档。
NodeJs MongoDB 原生使用 - returnOriginal: false
【参考方案2】:
默认情况下findOneAndUpdate 返回原始文档。如果您希望它返回修改后的文档,请将选项对象 new: true
传递给函数:
Cat.findOneAndUpdate( age: 17 , $set: name: "Naomi" , new: true , function(err, doc)
);
【讨论】:
为什么_id
为空?【参考方案3】:
对于使用带有原生承诺的 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 */
【讨论】:
如果您不提供回调函数,Mongoose 将返回一个承诺。无需创建自己的承诺! 如果您不提供回调,@joeytwiddle Mongoose 不会返回 Promise。相反,它返回一个仅提供一小部分 Promise API 的 Query 对象。这是根据猫鼬文档。【参考方案4】:对于使用 Node.js 驱动程序而不是 Mongoose 的任何人,您需要使用 returnOriginal:false
而不是 new:true
。
2021 - Mongodb ^4.2.0 更新 returnDocument: 'after'
【讨论】:
谢谢!这适用于我 mongodb 节点版本 2.2.27 这是一种愚蠢的 API。为什么不对 Mongoose 使用与原生 API 相同的签名?为什么不默认返回更新的文档? Mongoose 是我每天使用的比较烦人的库之一。 我正在使用"mongodb": "^3.6.9"
和 returnOriginal:false
已弃用。请改用 returnDocument: 'after'
。
谢谢!这对我有用。 @kunthet 我实际上正在使用它,因为文档解释说建议的 returnOriginal: false
已弃用。但由于某种原因,我无法让它发挥作用,而使用建议可以按预期工作。【参考方案5】:
这是findOneAndUpdate
的更新代码。它有效。
db.collection.findOneAndUpdate(
age: 17 ,
$set: name: "Naomi" ,
returnNewDocument: true
)
【讨论】:
【参考方案6】:因此,“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
【讨论】:
Laravel:'returnDocument' => FindOneAndUpdate::RETURN_DOCUMENT_AFTER
【参考方案7】:
如果您想返回更改后的文档,您需要设置选项new:true
API 参考您可以使用Cat.findOneAndUpdate(conditions, update, options, callback) // executes
由Mongoose官方APIhttp://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);
);
【讨论】:
【参考方案8】:下面显示了对 mongoose 的findOneAndUpdate
的查询。这里new: true
用于获取更新的doc,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();
【讨论】:
【参考方案9】:这里是 Mongoose 的维护者。您需要将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。
【讨论】:
我误写了 returnNewDocument 而不是 new。感谢您的帮助! 如何在没有异步的情况下使用 await? 你不能@PeterXX 那只是一个代码sn-p。【参考方案10】:我知道,我已经迟到了,但让我在这里添加我的简单有效答案
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)
【讨论】:
【参考方案11】:在某些情况下,new: true
不起作用。
那你可以试试这个。
'returnNewDocument':true
【讨论】:
【参考方案12】:2021 - Mongodb ^4.2.0 更新
这适用于 mongodb 节点驱动程序,NOT mongoose。
如果您使用“collection.findOneAndUpdate”进行搜索和更新,最新版本的 Mongodb 节点驱动程序似乎使用以下语法:
.findOneAndUpdate(query, update, returnDocument: 'after' | 'before' )
搜索时自己在这里找不到答案,所以发布这个以防其他人处于同样的情况。
【讨论】:
这没有提供问题的答案。一旦你有足够的reputation,你就可以comment on any post;相反,provide answers that don't require clarification from the asker。 - From Review以上是关于Mongoose:findOneAndUpdate 不返回更新的文档的主要内容,如果未能解决你的问题,请参考以下文章
Mongoose:findOneAndUpdate 不返回更新的文档
Mongoose - 使用 findOneAndUpdate 更新子文档
Mongoose `findOneAndUpdate` 回调不传递更新的文档
Mongoose `findOneAndUpdate` 回调不传递更新的文档