在MongoDB中更新和返回文档

Posted

技术标签:

【中文标题】在MongoDB中更新和返回文档【英文标题】:Update And Return Document In 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();
                );

有什么想法吗?

【问题讨论】:

【参考方案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: falsev5.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)

【讨论】:

以上是关于在MongoDB中更新和返回文档的主要内容,如果未能解决你的问题,请参考以下文章

findOneAndUpdate 未在 MongoDb 中返回更新的文档 [重复]

找不到 id 并更新和增加子文档 - 返回 null Mongoose/mongoDB

mongodb findOneAndUpdate 只获取更新的字段

mongodb 没有则插入,有则更新其中某列

怎么使用java操作mongodb更新整个文档

MongoDB 通知文档更新