我正在尝试使用Postman更新带有文件名的数组来测试API。 当我用mongo查询它时,数组是空的。 具有图像数组的用户模型:
var UserSchema = new Schema({
name: String,
email: { type: String, required: true, validate: [validate.email, 'invalid email address'],
index: { unique: true }},
password: { type: String, required: true, select: false },
images: [{ name: String }]
});
apiRouter express路由器:
apiRouter.put('/images/:user_id/:file_name', function(req, res){
User.findById(req.params.user_id, function(err, user) {
//console.log(req.params.user_id);
//console.log(req.params.file_name);
user_id = req.params.user_id;
file_name = req.params.file_name;
user.update({$addToSet:{'images': file_name}});
user.save(function(err) {
if (err) return res.send(err);
res.json({ message: 'User updated!' });
});
});
});
邮差:
PUT http://localhost:3000/api/images/5626fd2903c49d6231518c9/imageA
和mongo db.find():
"images" : [ ]
file_name包含正确的" imageA"值,但正如您所见,images数组为空。
答案 0 :(得分:0)
你这样做是错的。像$addToSet
这样的运算符的更新是原子的,这意味着它们直接在数据库上进行更改,然后用它完成。
所以像.update()
之类的调用需要一个用于匹配文档的查询组件和一个"更新"用于修改匹配文档的组件:
apiRouter.put('/images/:user_id/:file_name', function(req, res) {
User.update(
{ "_id": req.params.user_id },
{ "$addToSet": {"images": req.params.file_name } },
function(err,numAffected) {
if (err) {
return res.send(err);
} else if ( numAffected == 0 ) {
res.json({ "message": "Not found" })
} else {
res.json({ "message": "User updated!" });
}
}
);
});
否则使用.findByIdAndUpdate()
返回修改后的文档:
apiRouter.put('/images/:user_id/:file_name', function(req, res) {
User.findByIdAndUpdate(req.params.user_id,
{ "$addToSet": {"images": req.params.file_name } },
{ "new": true },
function(err,user) {
if (err) {
return res.send(err);
} else if ( !user ) {
res.json({ "message": "Not found" })
} else {
res.json(user);
}
}
);
});
另请注意,如果没有匹配的文档来执行更新,它不是err
,而是受影响的文档将是0
,或者在后一个功能案例中将没有文件归还。
当您检索到文档并在常规代码而非数据库方法中修改了内容时,您只使用.save()
之类的方法。 "检索/修改/保存"这不是一个好习惯。因为其他操作可能会在发生的那些操作之间更新数据库中的文档,从而使您覆盖信息和状态不一致。