【问题标题】:Update And Return Document In Mongodb在MongoDB中更新和返回文档
【发布时间】:2014-09-04 23:57:52
【问题描述】:

我想获取更新的文档。这是我的原始代码,它成功更新但不返回文档。

collection.update({ "code": req.body.code },{$set:  req.body.updatedFields}, function(err, results) {
                        res.send({error: err, affected: results});
                        db.close();
                    });

我使用了toArray 函数,但这给出了错误“如果没有提供回调,就无法使用 writeConcern”:

collection.update({ "code": req.body.code },{$set:  req.body.updatedFields}).toArray( function(err, results) {
                    res.send({error: err, affected: results});
                    db.close();
                });

有什么想法吗?

【问题讨论】:

    标签: node.js mongodb


    【解决方案1】:

    检查 WriteResult 对象:

    http://docs.mongodb.org/manual/reference/method/db.collection.update/#writeresults-update

    WriteResult result = collection.update({ "code": req.body.code },{$set:  req.body.updatedFields}, function(err, results) {
                        res.send({error: err, affected: results});
                        db.close();
                    });
    

    结果应该是这样的:

    WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
    

    如果您想要更新的结果,请使用主键执行另一个查询。

    【讨论】:

    • 这仅提供统计信息,不提供更新的文档
    【解决方案2】:

    collection.update() 只会将受影响的文档数报告给它自己的回调。

    要在修改时检索文档,您可以改用collection.findOneAndUpdate()(以前的.findAndModify())。

    collection.findOneAndUpdate(
        { "code": req.body.code },
        { $set: req.body.updatedFields },
        { returnOriginal: false },
        function (err, documents) {
            res.send({ error: err, affected: documents });
            db.close();
        }
    );
    

    returnOriginal 选项(或带有 Mongoose 的 new)可让您指定将找到的文档的哪个版本(原始 [默认] 或更新)传递给回调。

    returnOriginal 在版本 3.6 中已弃用。将returnDocument: "before" | "after" 用于3.6 及更高版本。


    免责声明:此答案目前指的是 version 3.6 的 Node.js 驱动程序。随着新版本的发布,请查看其文档以了解可能的新弃用警告和推荐的替代方案。

    【讨论】:

    • 文档建议它只做一个文档,而不是多个 --
    • 现在已弃用。请改用collection.findOneAndUpdate!
    • findOneAndUpdate 似乎以修改前的状态检索文档。我认为问题的目标是获取结果对象
    • 将 returnOriginal 选项设置为 false 会返回更新后的对象
    • 目前我使用的是 ^5.10.9 版本的 mongoose 包,可以使用 new:true 代替 returnOriginal:false,效果很好。
    【解决方案3】:

    找不到任何方法来更新许多并返回docs 中的修改记录,所以我做了一个解决方法。

    我可以通过以下方法找到的至少一个错误是,您无法判断文档是否被修改或已经具有您正在使用的值:

    function findAndUpdateMany(filter, updateOptions) {
      return collection.find(filter).project({_id: 1}).toArray()
        .then(function(matchingIds) {
          filter = {_id: {$in: matchingIds}}
          return collection.updateMany(filter, updateOptions)
        }).then(function() {
          return collection.find(filter).toArray()
        })
    }
    

    【讨论】:

      【解决方案4】:

      解决办法是设置:{returnOriginal: false}。

      collection.findOneAndUpdate(
              whereObj,
              updateObj,
              {returnOriginal: false});
      

      【讨论】:

      • 目前我使用的是 ^5.10.9 版本的 mongoose 包,可以使用 new:true 代替 returnOriginal:false,效果很好。
      【解决方案5】:

      如果您使用的是猫鼬,returnOriginal: false 在v5.11.10 对我不起作用,

      但new: true 工作,

      from official mongoose docs:

      const filter = { name: 'Jean-Luc Picard' };
      const update = { age: 59 };
      
      let doc = await Character.findOneAndUpdate(filter, update, {
        new: true
      });
      doc.name; // 'Jean-Luc Picard'
      doc.age; // 59
      

      【讨论】:

      • 那是因为你使用的是 Mongoose,一个建立在 MongoDB 之上的库,而问题是关于 MongoDB。
      【解决方案6】:

      要在对一个文档执行更新操作时获取更新的文档,请使用 findOneAndUpdate() 并在选项对象中,将 returnDocument 属性设置为 'after'

      let options = {returnDocument: 'after'}

      const upadatedDoc = collection.findOneAndUpdate({'your query'},{'your update'}, options)

      【讨论】:

        猜你喜欢
        • 2020-05-06
        • 2017-01-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-05-06
        • 2020-05-24
        • 1970-01-01
        • 2023-01-30
        相关资源
        最近更新 更多