You need to enable JavaScript to run this app. Node.js异步函数中使用push操作MongoDB出现相同ID重复记录问题
优惠活动
大模型
产品
解决方案
定价
更多

Node.js异步函数中使用push操作MongoDB出现相同ID重复记录问题

问题根因

  • 你当前混用了 async/await 异步语法和Mongoose的回调写法,导致异步逻辑混乱:Mongoose的查询方法如果传入回调函数,就不会返回Promise,外层的try/catch无法捕获到更新操作的错误,甚至可能出现响应未正确返回、前端重复触发请求的情况。
  • $push 操作本身默认允许插入重复元素,你没有做接口幂等校验,一旦前端重复触发请求(比如用户多次点击提交、前端自动重试),就会生成多条重复评论。
  • 你没有对同一用户的高频重复提交做拦截,相同参数短时间多次调用接口就会插入多条重复数据。

修复方案

  1. 首先统一异步写法,移除回调,全用async/await,确保错误能被正常捕获、响应能正确返回:
module.exports.commentPost = async (req, res) => {
  // 建议先放开注释的ID合法性校验,提前拦截非法请求
  if (!ObjectID.isValid(req.params.id)) {
    return res.status(400).send("ID unknown : " + req.params.id);
  }
  const check_post = await PostModel.exists({ _id: req.params.id });
  if (!check_post) {
    return res.status(400).send("ID unknown : " + req.params.id);
  }

  try {
    // 新增重复提交校验:判断同一用户10秒内是否给同一条帖子提交过相同内容的评论
    const post = await PostModel.findById(req.params.id);
    const recentDuplicate = post.comment.find(item => 
      item.commenterId === req.body.commenterId 
      && item.text === req.body.text 
      && Date.now() - item.timestamp < 10 * 1000
    );
    if (recentDuplicate) {
      return res.status(400).send("请勿重复提交评论");
    }

    // 移除回调,用await接收更新结果
    const updatedPost = await PostModel.findByIdAndUpdate(
      req.params.id,
      {
        $push: {
          comment: {
            commenterId: req.body.commenterId,
            commenterPseudo: req.body.commenterPseudo,
            text: req.body.text,
            timestamp: new Date().getTime(),
          },
        },
      },
      { new: true }
    );
    return res.send(updatedPost);
  } catch (err) {
    return res.status(400).send(err);
  }
};
  1. 前端配合做提交防抖:评论提交按钮点击后立即置灰,直到接口返回成功/失败结果后再恢复可点击状态,避免用户误点多次触发请求。
  2. 如果需要彻底避免完全相同的评论插入,可以给评论对象新增唯一的请求标识字段(比如前端生成的requestId),把$push改成$addToSet,只要requestId相同就不会重复插入。

内容的提问来源于stack exchange,提问作者byrd reda

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.11 22:27:02