我试图确定是否在我的findOneAndUpdate操作中找到了该文档。如果它不是,我返回404未找到错误。我想我会使用" passRawValue"选项Mongoose提供并检查原始值 - 如果raw未定义,我知道找不到doc。
但无论是否找到doc,我的原始值都是未定义的。我通过运行一个简单的" findOne"来验证我在查询时尝试更新的文档是在数据库中。在更新之前查询。我哪里错了?
let updateItemById = (userId, itemId, params, cb) => {
//this finds and prints the document I'm testing with -- I know its in the DB
// Item.findOne({ "_id" : itemId, ownerId: userId }, (err, doc) => {
// if (doc) {
// console.log("This is the doc: ", doc);
// }
// });
Item.findOneAndUpdate({ "_id" : itemId, ownerId: userId },
{
$set: {
params
}
}, { runValidators: 1, passRawResult: true}, (err, doc, raw) => {
if (err) {
//winston.log
return cb(ErrorTypes.serverError(), false);
}
else if (raw) {
return cb(null, true);
}
else {
return cb(ErrorTypes.notFound(), false);
}
});
}
答案 0 :(得分:1)
您好我有预感,您传递的params具有数据库中文档中不存在的属性。在这种情况下,没有任何内容被修改,因此db不会将raw作为第三个参数返回。
<强>更新强>
所以我做了一些自己的测试,我看到如果我们传递option strict:false,那么你的代码应该按预期工作。因此,您的选项部分将如下所示
{ runValidators: 1, passRawResult: true, strict: false, new:true}
<强>解释强>
Mongoose的strict option默认为true。它确保在架构中定义要更新的值。因此,当我们提供严格为false的选项时,如[mongoose documentation](http://mongoosejs.com/docs/api.html#query_Query-findOneAndUpdate)中所述,我们可以用新字段实现更新文档。
我还添加了new:true选项,它会返回更新的文档。
<强> P.S。强>
我想补充一下,因为我们的 upsert 为false,这意味着当找不到匹配项时它不会插入新文档,它会为doc返回null,而你可以简单地检查一下。你为什么要检查原始?这有什么特别的原因吗?
答案 1 :(得分:0)
我知道已经有一段时间了,但是我在这里遇到了同样的问题,所以我决定留下一个可能对其他人有帮助的答案。
通过检查回调函数中的 doc 参数是否为空,我能够检查 findOneAndUpdate()方法是否找到了文档:
async Update(request: Request, response: Response) {
const productId = request.params.id;
const query = { _id: productId };
const options = { new: true };
try {
await Product.findOneAndUpdate(query, request.body, options, (err, doc, res) => {
if (doc === null)
return response.status(404).send({
error: 'Product not found'
})
return response.status(204).send();
});
}
catch (err) {
return response.status(400).send({
error: 'Product update failed'
});
}
}