【问题标题】:Mongoose - MongoDB issue - VersionError: No matching document found for id "60bf5b73de309f1a30fe88a2" version 10 modifiedPaths "likes"Mongoose - MongoDB 问题 - VersionError: No matching document found for id "60bf5b73de309f1a30fe88a2" version 10 modifiedPaths "likes"
【发布时间】:2021-08-26 00:18:03
【问题描述】:

在开发我的全栈应用程序(这是一个 facebook 克隆)时,我在我的服务器中发现了这个错误,我不知道如何解决它。

我正在使用 node.js、express、mongodb、mongoose 和 typescript,并且,在开发点赞出版物的路线中,发生了这个错误(以及在点赞 cmets 路线中)。

错误

VersionError: No matching document found for id "60bf5b73de309f1a30fe88a2" version 10 modifiedPaths "likes"
    at generateVersionError (C:\Users\diego cifuentes\Desktop\Portafolio\Fullstack Projects\Facebook - MERN ( with next.js )\backend\node_modules\mongoose\lib\model.js:432:10)
    at model.Model.save (C:\Users\diego cifuentes\Desktop\Portafolio\Fullstack Projects\Facebook - MERN ( with next.js )\backend\node_modules\mongoose\lib\model.js:488:28)
    at C:\Users\diego cifuentes\Desktop\Portafolio\Fullstack Projects\Facebook - MERN ( with next.js )\backend\src\controllers\publication.ts:166:18
    at Generator.next (<anonymous>)
    at fulfilled (C:\Users\diego cifuentes\Desktop\Portafolio\Fullstack Projects\Facebook - MERN ( with next.js )\backend\src\controllers\publication.ts:5:58)
    at runMicrotasks (<anonymous>)
    at processTicksAndRejections (internal/process/task_queues.js:93:5) {
  version: 10,
  modifiedPaths: [ 'likes' ]
}
VersionError: No matching document found for id "60bf5b73de309f1a30fe88a2" version 10 modifiedPaths "likes"
    at generateVersionError (C:\Users\diego cifuentes\Desktop\Portafolio\Fullstack Projects\Facebook - MERN ( with next.js )\backend\node_modules\mongoose\lib\model.js:432:10)
    at model.Model.save (C:\Users\diego cifuentes\Desktop\Portafolio\Fullstack Projects\Facebook - MERN ( with next.js )\backend\node_modules\mongoose\lib\model.js:488:28)
    at C:\Users\diego cifuentes\Desktop\Portafolio\Fullstack Projects\Facebook - MERN ( with next.js )\backend\src\controllers\publication.ts:166:18
    at Generator.next (<anonymous>)
    at fulfilled (C:\Users\diego cifuentes\Desktop\Portafolio\Fullstack Projects\Facebook - MERN ( with next.js )\backend\src\controllers\publication.ts:5:58)
    at runMicrotasks (<anonymous>)
    at processTicksAndRejections (internal/process/task_queues.js:93:5) {
  version: 10,
  modifiedPaths: [ 'likes' ]
}

这仅在客户端用户尝试多次单击“赞”按钮时发生,因此,问题没有给操作足够的时间与服务器交互。

我一直在寻找解决方案,并且我看到人们在这种情况下提到 .update() 而不是 .save,但是,我无法真正理解 .update() 的具体含义以及为什么它可能解决这个问题。

为了给你更多的上下文,这就是喜欢酒吧路线的逻辑

// Like Publication

export const likePublication = async (req: Request, res: Response) => {
  const { publicationId } = req.params;

  const { identifier } = req.body;

  // Check id's

  if (!mongoose.Types.ObjectId.isValid(identifier!))
    return res.status(400).json({ Message: "identifier not valid" });

  if (!mongoose.Types.ObjectId.isValid(publicationId!))
    return res.status(400).json({ Message: "identifier not valid" });

  // Find pub

  const thePub: Ipub = await Publication.findById(publicationId);

  // Find user

  const theUser: Iauth = await User.findById(identifier);

  try {
    // Check if user already liked, if not, like the pub
    if (thePub.likes!.find(f => f.identifier === theUser.id) === undefined) {
      thePub.likes!.push({ identifier: theUser.id! });
    }
    // Check if user already liked, if user liked, cut like
    else if (thePub.likes!.find(f => f.identifier === theUser.id)) {
      thePub.likes = thePub.likes!.filter(
        filt => filt.identifier !== theUser.id!
      );
    }

    // Save

    await thePub.save();

    return res.json(thePub);
  } catch (err) {
    console.log(err);
    return res.status(500).json({ Error: "the API failed" });
  }
};

我该怎么办?谢谢!

【问题讨论】:

  • 这看起来像是一个互斥锁的工作。

标签: node.js typescript mongodb express mongoose


【解决方案1】:

由于您控制全栈,在前端部分,您可以在向服务器发送请求时使用 BlockUI 来阻止屏幕。这将防止用户在处理请求但尚未完成时执行多个请求。

【讨论】:

  • 不知道有这个,可以试试,谢谢解答!
【解决方案2】:

当您保存文档时,MongoDB 会自动增加文档的版本号。 在保存操作之前,它将比较传入文档的版本号和集合中的现有文档。如果传入的文档版本低于集合中的版本,则会抛出“未找到匹配的文档”错误。当用户非常快地点击赞按钮时,await Publication.findById(publicationId); 可能不会返回最新的文档,因为之前的保存操作可能没有完成。处理此问题的一种方法是在从前端调用likePublication 路由时设置去抖动时间。否则,你必须抓住这个错误并再次尝试点赞。

// Like Publication
const maxRetry = 3;
async function likePublication(publicationId:ObjectId, identifier:ObjectId, retryCount = 0) {
  if(retryCount > maxRetry) {
    throw new Error("Max retry reached");
  }
  // Find pub

  const thePub: Ipub = await Publication.findById(publicationId);

  // Find user

  const theUser: Iauth = await User.findById(identifier);

  try {
    // Check if user already liked, if not, like the pub
    if (thePub.likes!.find(f => f.identifier === theUser.id) === undefined) {
      thePub.likes!.push({ identifier: theUser.id! });
    }
    // Check if user already liked, if user liked, cut like
    else if (thePub.likes!.find(f => f.identifier === theUser.id)) {
      thePub.likes = thePub.likes!.filter(
        filt => filt.identifier !== theUser.id!
      );
    }

    // Save

    return thePub.save();
  } catch (err) {
    if(err.message.indexOf("No matching document found") > -1) {
      return likePublication(publicationId, identifier, retryCount+1);
    }
    throw err;
  }
}

export const likePublicationHandler = async (req: Request, res: Response) => {
  const { publicationId } = req.params;

  const { identifier } = req.body;

  // Check id's

  if (!mongoose.Types.ObjectId.isValid(identifier!))
    return res.status(400).json({ Message: "identifier not valid" });

  if (!mongoose.Types.ObjectId.isValid(publicationId!))
    return res.status(400).json({ Message: "identifier not valid" });
  try {
    const thePub = await likePublication(publicationId, identifier);

    return res.json(thePub);
  } catch (err) {
    console.log(err);
    return res.status(500).json({ Error: "the API failed" });
  }
};

【讨论】:

  • 谢谢你的回答,现在我必须在这个和 blocUI 之间做出选择,再次感谢!
猜你喜欢
  • 2014-10-08
  • 2014-12-20
  • 2022-12-19
  • 2020-03-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-20
  • 2019-05-07
相关资源
最近更新 更多