【问题标题】:Mongoose save() returning old version, not saved version of documentMongoose save() 返回旧版本,未保存的文档版本
【发布时间】:2019-02-13 05:00:21
【问题描述】:

我一定遗漏了一些东西,但我的 Document.prototype.save() 在 Mongoose 5.2.10 中似乎无法正常工作。

The docs say 回调返回保存的文档

回调将接收两个参数

  • err如果发生错误
  • product 这是得救了 product

对我来说,它似乎是在更新和保存之前返回文档的原始版本。要么我做错了什么,要么文档有点误导或含糊。

调用save后,文档在数据库中更新,但是回调返回的是修改前的旧文档。

我一直在这样调用 save(在异步函数中):

const myDocument = await User.findOne({ name: 'billy' });
const updatedInfo = {
    foo: 'update here',
    bar: 'some other new stuff'
};
myDocument.update({ $set: updatedInfo }, (err) => { console.log(err) });
myDocument.save((err, savedDoc) => {
    if (err) { console.log(err); }
    // Should return saved doc here
    console.log(savedDoc);
});

像这样:

myDocument.update({ $set: updatedInfo }, (err) => { console.log(err) });
myDocument.save().then((savedDoc) => {
    // Should return saved doc here
    console.log(savedDoc);
}).catch((err) => { console.log(err); });

但无法让它返回我保存的文档。 savedDoc 最终成为文档的旧版本,而新版本确实保存在数据库中。

【问题讨论】:

  • 请查看此链接https://davidburgos.blog/return-updated-document-mongoose/
  • 感谢您提供该链接。我已经看到了,但我实际上是在问一些不同的东西。我不想查询和更新文档,而是想知道如何获取已查询的文档的保存版本。在这里与 Mongoose 人进行了很好的讨论:github.com/Automattic/mongoose/issues/6993

标签: javascript database mongodb mongoose


【解决方案1】:

使用findOneAndUpdate{new : true} 获取新版本

Model.findOneAndUpdate({statue: 'active'}, {$set:{qtt:0}}, {new: true}, function(err, doc){
    if(err){
        console.log("Something wrong when updating data!");
    }

    console.log(doc);
});

【讨论】:

  • 这是可能的,但就我的用例而言,如果我可以更新我已经在查看的文档,而不必重新查找并更新它,那就太好了。这里还有更多讨论:github.com/Automattic/mongoose/issues/6993
【解决方案2】:

使用the help of some of the Mongoose collaboraters,我发现问题在于我同时使用了document.update() 函数和document.save() 函数。

document.update() 函数是一个带有回调的单独异步操作,正如@Industrial Comet 所述,它不返回文档。

为了进行将应用于已保存、返回的文档版本的更改,您需要以以下形式将每个更改直接应用于文档对象:

myDocument.foo = 'new info';  
myDocument.bar = 'other new info';
myDocument.save((err, newDocument) => {
   // new Document available here
});

编辑:

I found out 您还可以使用myDocument.set(objectOfUpdatedInfo) 使用更新信息的对象 更新一堆不同的值,然后使用myDocument.save() 返回保存的文档。

所以我的解决方案是这样做:

myDocument.set(objectOfUpdatedInformation);
myDocument.save().then((savedDoc) => {
    res.json({ response: 'success' savedDoc: savedDoc });
}).catch((err) => { console.log(err); });

以下是我在知道document.protype.save() 存在之前对情况的初步评估。 (因为没有仔细阅读文档而让自己感到额外的悲痛)

但我想用对象中的一大块不同字段来更新我的文档。我希望能够做到这一点,然后得到一个更新的文件。看起来我不能用 myDocument.update(objectOfUpdatedInfo) 做到这一点,因为:

  • .update() 方法未在回调中提供更新的信息
  • 如果我在 .update() 方法之后使用保存,则更改不会显示在返回的保存文档中。

所以我的选择是:

  • 将更改应用到对象中的单个键/值,然后.save()它。
  • 重新查询对象并用Collection.findOneAndUpdate()更新它。

Document.save()Collection.findOneAndUpdate() 都返回更新的文档,但 Document.save() 不能很好地与 Document.update() 配合使用,Document.update() 不返回文档。p>

我希望能够将一个充满更新信息的对象干净地插入到已经查询的myDocument 对象中,然后返回更新文档,但不幸的是,现在这似乎没有可能在猫鼬。我问过这个问题,可能会有进一步的讨论in this github issue。目前,这是我选择的使用计算键值更新的解决方案:

// Need to a document with an object full of values...
for (var property in updatedInfo) {
    myDocument[property] = updatedInfo[property];
}
myDocument.save().then((savedDoc) => {
    res.json({ response: 'success' savedDoc: savedDoc });
}).catch((err) => { console.log(err); });

【讨论】:

    【解决方案3】:

    Mongoose 更新函数不返回更新后的 Doc。此外,使用 update 函数进行的更改是单独的异步操作,不应与 update 函数一起使用。

    1. 先查询文档
    2. 通过为各个键分配新值来修改文档
    3. 保存并返回更新的文档

      docs.findById(id,(err,myDocument)=> { //选择要更改的文档 myDocument.foo = //更新内容 myDocument.save((err,newDocument)=> { //返回新文档 }) })

    【讨论】:

    • 我先查询文档,我只是没有在上面的代码中包含它。现在我已经对其进行了编辑以显示。
    猜你喜欢
    • 1970-01-01
    • 2014-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-04
    • 1970-01-01
    • 2016-05-10
    • 1970-01-01
    相关资源
    最近更新 更多