node.js 使用 Mongoose 更新 _id = :id 的记录
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17250496/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Update a record where _id = :id with Mongoose
提问by Syl
I'm trying to update an existing record with Mongoose. The insert is OK but not the update.
我正在尝试使用猫鼬更新现有记录。插入没问题,但更新不行。
Here is my snippet:
这是我的片段:
app.post('/submit', function(req, res) {
var my_visit = new models.visits({
date: req.body.visit_date,
type: req.body.visit_type,
agency: req.body.visit_agency,
city: req.body.visit_city,
url: req.body.visit_url,
note: req.body.visit_note
});
// INSERT
if(req.body.id == 0) {
my_visit.save(function(err) {
if(err) { throw err; }
console.log('added visit');
res.redirect('/');
});
} else { // UPDATE
var upsertData = my_visit.toObject();
console.log(req.body.id); // OK
models.visits.update({ _id: req.body.id }, upsertData, { multi: false }, function(err) {
if(err) { throw err; }
console.log('updated visit: '+ req.body.id);
res.redirect('/');
});
}
})
The response is Mod on _id is not allowed.
回应是Mod on _id is not allowed。
I just want to update the line such as WHERE id = idin MySQL. I didn't find the right syntax.
我只想更新诸如WHERE id = idMySQL之类的行。我没有找到正确的语法。
回答by verybadalloc
According to this questionand this other one, the Mod on _id is not allowedoccurs when one tries to update an object based on its id without deleting it first.
根据this question和this other one,Mod on _id is not allowed当一个人尝试根据其id更新一个对象而不先删除它时会发生这种情况。
I also found this github issuewhich tries to explain a solution. It explicitly states:
我还发现了这个github 问题,它试图解释一个解决方案。它明确指出:
Be careful to not use an existing model instance for the update clause (this won't work and can cause weird behavior like infinite loops). Also, ensure that the update clause does not have an _id property, which causes Mongo to return a "Mod on _id not allowed" error.
注意不要将现有的模型实例用于更新子句(这将不起作用,并可能导致像无限循环这样的奇怪行为)。此外,请确保更新子句没有 _id 属性,这会导致 Mongo 返回“不允许 _id 上的修改”错误。
The solution, it seems, is to do the following:
解决方案似乎是执行以下操作:
var upsertData = my_visit.toObject();
console.log(req.body.id); // OK
delete upsertData._id;
models.visits.update({ _id: req.body.id }, upsertData, { multi: false }, function(err) {
if(err) { throw err; }
//...
}
On a side note, you can probably rewrite your route to do both the create and update without the if-else clause. update()takes an extra option upsert, which, according to the docs:
附带说明一下,您可以重写路由以在没有 if-else 子句的情况下进行创建和更新。update()需要一个额外的选项upsert,根据文档:
upsert (boolean) whether to create the doc if it doesn't match (false)
upsert (boolean) 如果不匹配,是否创建文档 (false)
回答by Derya Cortuk
Here is my solution:
这是我的解决方案:
routes/router.js
router.patch('/user/:id', userController.updateUser)
exports.updateUser = async(req, res) => { const updates = Object.keys(req.body) const allowedUpdates = ['name', 'email', 'password', 'age'] const isValidOperation = updates.every((update) => allowedUpdates.includes(update)) if (!isValidOperation) { return res.status(400).send('Invalid updates!') } try { const user = await UserModel.findByIdAndUpdate(req.params.id, req.body, { new: true, runValidators: true }) if (!user) { return res.status(404).send() } res.status(201).send(user) } catch (error) { res.status(400).send(error) } }
exports.updateUser = async(req, res) => { const updates = Object.keys(req.body) const allowedUpdates = ['name', 'email', 'password', 'age'] const isValidOperation = updates.every((update) => allowedUpdates.includes(update)) if (!isValidOperation) { return res.status(400).send('Invalid updates!') } try { const user = await UserModel.findByIdAndUpdate(req.params.id, req.body, { new: true, runValidators: true }) if (!user) { return res.status(404).send() } res.status(201).send(user) } catch (error) { res.status(400).send(error) } }

