MongooseJS:`TypeError:Object#<object>没有方法'save'`:无法保存文档的一部分?</object>

时间:2014-08-31 07:01:34

标签: javascript node.js mongodb mongoose mongodb-query

我正在寻找关于如何检索数组元素的堆栈溢出,我在这里看到这个链接就找到了:

仅检索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'。有想法该怎么解决这个吗?谢谢!

1 个答案:

答案 0 :(得分:3)

是的,所以这不再是一个猫鼬文件了。它不能是一个,因为你使用“投影”,这意味着不一定返回所有字段。事实上,并不是因为你只返回所有可能字段中的“朋友”数组。

这意味着即使这是一个mongoose文档,.save()也将完全无效,因为如果你试图“强制转换”会发生什么,你最终只用一个字段覆盖所有现有的文档内容

所以你的方法归结为:

  1. 不要使用投影并在使用.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
         });
     });
    
  2. 只需使用原子更新来修改文档。可能更安全,因为你不能保证其他东西没有修改文件,因为你读它,但当然删除所有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
    
        }
    );
    
  3. 因此,我们意识到在某些情况下,无法在响应中返回完整的文档对象,否则您需要手动转换为一个,但它可能不会与源相同。

    第二种形式基本上存在,以确保两个操作之间不发生任何更改。即使您需要实现其他逻辑,通常也会更好,但如果您不需要在模型上进行其他计算和挂钩,也会更好。