You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在MongoDB的findOneAndUpdate中区分插入/更新修改文档

解决方案

你可以利用MongoDB的聚合表达式操作符($cond、$add、$exists)来区分插入和更新场景,实现需求。同时要修正原代码中then方法的调用问题(原写法会提前发送响应)。修改后的代码如下:

upsert = (req, res) => {
  return Promise.all(req.body.map(resource => {
    return Resource.findOneAndUpdate(
      { resource_id: resource.id },
      {
        $set: {
          title: resource.title,
          seller_id: resource.seller_id,
          initial_quantity: resource.quantity,
          // 核心逻辑:判断是否为新插入文档,设置对应quantity值
          quantity: {
            $cond: {
              if: { $exists: ["$quantity", true] }, // 存在quantity字段说明是更新操作
              then: { $add: ["$quantity", resource.quantity] }, // 更新时累加传入的数量
              else: 0 // 插入时设置为0
            }
          }
        }
      },
      { upsert: true, new: true }
    );
  }))
  .then(() => { // 修正:在回调内发送响应,确保Promise完成后执行
    res.status(200).json({ message: "OK" });
  })
  .catch(err => {
    console.log(err);
    res.status(500).json({ message: "Error" });
  });
}

关键逻辑说明

  • $exists: ["$quantity", true]:判断当前文档是否存在quantity字段,新插入的文档不存在该字段,因此会触发else分支设为0;已有文档存在该字段,触发then分支执行累加。
  • $add: ["$quantity", resource.quantity]:将数据库中原有quantity值与请求传入的数量相加,实现更新时的累加需求。
  • 修正then的调用方式:原代码直接执行res.status(200).json(...)会导致在Promise.all未完成时就发送响应,改为在回调函数内执行,确保所有数据库操作完成后再返回结果。

注意事项

  • 该方案依赖MongoDB 3.6及以上版本,因为需要支持在更新操作中使用聚合表达式。
  • 确保resource.quantity是数值类型,避免加法操作出现异常。

内容的提问来源于stack exchange,提问作者Luis Urán

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.03 22:45:36