我正在尝试使用Mongoose更新现有记录。插入没有问题,但没有更新。
这是我的代码:
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('/');
});
}
})
回复是Mod on _id is not allowed
。
我只想更新MySQL中的WHERE id = id
等行。我找不到合适的语法。
答案 0 :(得分:15)
根据this question和this other one,当{1}}尝试根据其ID更新对象而不首先删除它时,会发生Mod on _id is not allowed
。
我还发现这个github issue试图解释一个解决方案。它明确指出:
小心不要将现有模型实例用于update子句 (这不起作用,可能导致像无限循环这样的奇怪行为)。 另外,确保update子句没有_id属性, 这导致Mongo返回“Mod on _id not allowed”错误。
似乎解决方案是执行以下操作:
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; }
//...
}
在旁注中,您可以重写路由以执行create和update,而不使用if-else子句。 update()需要额外的选项upsert
,根据文档:
upsert(boolean)是否创建doc,如果它不匹配(false)
答案 1 :(得分:0)
这是我的解决方法:
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) } }