【问题标题】:Mongoose - Version Error: No matching document found for idMongoose - 版本错误:找不到与 id 匹配的文档
【发布时间】:2017-12-26 15:23:55
【问题描述】:

上下文:我有一个 Post Mongoose 模型,其中包含一个 csv_files 数组字段来存储 csv 字符串。我从另一个 Web 应用程序发出 fetch API 请求,以 POST 特定 Post 的 csv 字符串。

下面的代码会产生错误

UnhandledPromiseRejectionWarning:未处理的承诺拒绝(拒绝 id:2):VersionError:找不到与 id "5966932399e969ad8013bedf" 匹配的文档

router.js

router.post('/posts/:url/upload-csv/:csv_name', (req, res) => {
  let csv_name = req.params.csv_name;
  let csv_string = csv_name+req.body.csv_string;

  Post.findOne({url: req.params.url})
    .then((post) => {
      if (post.csv_files.length === 0) {
        post.csv_files.push(csv_string);
      } else {
        let foundExistingCSV = false;
        for (var i = 0; i < post.csv_files.length; i++) {
          if (post.csv_files[i].includes(csv_name)) {
            foundExistingCSV = true;
            post.csv_files[i] = csv_string;
            break;
          }
        }
        if (!foundExistingCSV) post.csv_files.push(csv_string);
      }

      post.markModified('csv_files');
      post.save();

      return res.status(200);
    })
    .catch((err) => {
      console.log(err);
      return res.status(400);
    });
});

models/post.js

const mongoose    = require('mongoose');

var stringPreset = {
  type: String,
  uppercase: true
}

var Post = mongoose.model('Post', {
  name                 : stringPreset,
  url                  : String,
  password             : String,
  csv_files            : { type : Array , "default" : [] },
  updatedAt            : { type: Date, default: Date.now }
});

module.exports = { Post };

如何解决此问题,以便文档保存到 csv_files 数组中而不会出现错误?

【问题讨论】:

  • 多个请求是否可能导致(几乎)同时处理同一个文档?
  • @robertklep 检查并发访问解决了我的问题,谢谢!你能写一个答案吗?

标签: javascript node.js mongodb csv mongoose


【解决方案1】:

看起来@robertklep 是对的。我通过将第一个 API 调用包装在 Promise 中来解决我的问题,然后在第一个 API 调用完成后执行第二个 API 调用。

我会等待将其标记为答案,以防万一有人遇到更好的解决方案。

【讨论】:

  • 我在 mongodb shell 中对集合进行了迁移和一些直接查询,现在我有不同 __v 的文档(其中一些是 4 和一些是5)。现在,当我第一次尝试更新时出现此错误,但在第二次尝试时它成功更新了它。删除所有__vs 字段或将所有文档更新到特定版本是否是个好主意。像这样:db.collectionName.updateMany({}, { __v: 5 })
【解决方案2】:

将对象保存到 Mongo DB 时,您必须了解 Mongo DB 有一个版本控制系统。这有助于确保如果您保存一次对象,再次保存时不会覆盖之前保存的数据。

这是您看到的错误。如果您想强制对象更新而不考虑此特定实例中的版本控制,您可能希望使用 .update() 代替。这将强制更新对象,无论其当前保存的状态如何。

这是因为 .save() 关注并关心版本控制,而 .update() 会更新对象而不考虑版本控制。

【讨论】:

  • 好的,这个答案解决了我的实际问题。但它给我带来了一个新的错误。 MongoError: Performing an update on the path '_id' would modify the immutable field '_id'
  • @dacopenhagen @ru4ert 我在 mongodb shell 中对集合进行了迁移和一些直接查询,现在我有不同 __v 的文档(其中一些是 4 个,其中一些是 5 个)。现在,当我第一次尝试更新时出现此错误,但在第二次尝试时它成功更新了它。删除所有__vs 字段或将所有文档更新到特定版本是否是个好主意。像这样的东西:db.collectionName.updateMany({}, { __v: 5 })
【解决方案3】:

只是在这里评论一下我的问题显然是什么。

错误信息:

message: '没有找到与 id "5c86d3a15bbcb965d85d80d1" 匹配的文档 版本 3',名称:'VersionError',版本:3

我的代码:

update: function (data) {

        var session = new Session(data);
        database.logging("INFO", "session-update", session.cid, session.order.orderNumber);
        return new Promise(function (resolve, reject) {

            session.save()
                .then(savedSession => resolve(savedSession))
                .catch(savedSessionError => reject(savedSessionError))
        });

    }

我的参数“数据”已经是一个 Mongoose 对象,我正在创建一个新对象并尝试 save() 它。所以就像@dacopenhagen 所说,save() 检查文档的版本并抛出 VersionError 错误。

我是如何解决的 只需删除 Session() 对象的创建。 删除了这一行

var session = new Session(data);

希望对你有所帮助。

【讨论】:

    【解决方案4】:

    我从正文的更新请求中删除了版本属性。

    删除 req.body.__v;

    【讨论】:

      【解决方案5】:

      虽然 .save() 在这里看起来是正确的方法,但 .update() 命令会在忽略导致此错误发生的“竞争条件”的同时完成工作。 Mongo DB 抛出此错误,因为它担心我保存的是已更新的旧版本文档:

      v1 发送给客户端 v1 已保存,并在 Mongo DB 中更新为 v2 v1 正在尝试再次保存,但 Mongo DB 已经存储了 v2,抛出错误 更好的方法是将 v1 发送给客户端,当购物车对象发生变化时,无论如何都要将对象与新的购物车对象同步。这可以通过 .update() 而不是通过 .save() 来完成。

      这是因为 .save() 监视并关心版本控制,而 .update() 将更新对象而不考虑版本控制。

      【讨论】:

        【解决方案6】:

        我遇到了同样的错误。 我使用了 findone.exec()。它对我有用

        【讨论】:

        • 您的答案可以通过额外的支持信息得到改进。请edit 添加更多详细信息,例如引用或文档,以便其他人可以确认您的答案是正确的。你可以找到更多关于如何写好答案的信息in the help center
        猜你喜欢
        • 2018-02-27
        • 2013-07-04
        • 2019-07-14
        • 2018-05-12
        • 1970-01-01
        • 2017-11-03
        • 2020-08-14
        • 2018-06-27
        • 1970-01-01
        相关资源
        最近更新 更多