我正在寻找关于如何检索数组元素的堆栈溢出,我在这里看到这个链接就找到了:
仅检索MongoDB集合中对象数组中的查询元素
以下是我根据以下问题创建的查询:
exports.confirmFriend = function(req, res){
if(req.body._id) {delete req.body._id}
User.findOne({'username': req.params.username}, {'friends': {$elemMatch: {'username': req.body.username}}}, function (err, user){
if(err) { return handleError(res, err); }
if(!user) { return res.send(404); }
//This is because $elemMatch returns only the first element so only 1 element will be populated
user.friends[0] = req.body;
user.save();
//Here I want to UPDATE or SAVE the document that I queried for now
});
现在我已经查询了我的user.friends元素并且我已经正确地使用正确的内容分配了req.body,我想知道,有没有办法更新或保存我执行此分配/查询的文档上?当我在作业结束时拨打user.save()
时,我收到一条错误消息:TypeError: Object #<Object> has no method 'save'
。有想法该怎么解决这个吗?谢谢!
答案 0 :(得分:3)
是的,所以这不再是一个猫鼬文件了。它不能是一个,因为你使用“投影”,这意味着不一定返回所有字段。事实上,并不是因为你只返回所有可能字段中的“朋友”数组。
这意味着即使这是一个mongoose文档,.save()
也将完全无效,因为如果你试图“强制转换”会发生什么,你最终只用一个字段覆盖所有现有的文档内容
所以你的方法归结为:
不要使用投影并在使用.save()
User.findOne({'username': req.params.username},function(err,user) {
user.friends.map(function(friend) {
if (friend.username == req.body.username)
friend = req.body;
return friend;
});
user.save(function(err,user) {
// do whatever
});
});
只需使用原子更新来修改文档。可能更安全,因为你不能保证其他东西没有修改文件,因为你读它,但当然删除所有mongoose验证和钩子:
User.findOneAndUpdate(
{
"username": req.params.username,
"friends.username": req.body.username
},
{
"$set": { "friends.$": req.body }
},
function(err,user) {
// do something with the now modified user
}
);
因此,我们意识到在某些情况下,无法在响应中返回完整的文档对象,否则您需要手动转换为一个,但它可能不会与源相同。
第二种形式基本上存在,以确保两个操作之间不发生任何更改。即使您需要实现其他逻辑,通常也会更好,但如果您不需要在模型上进行其他计算和挂钩,也会更好。