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

如何用Node.js+Mongoose实现MongoDB中对象数组的增改逻辑

在Mongoose中实现MongoDB数组元素的“存在则更新,不存在则添加”操作

方案一:分步更新(低并发场景适用)

先尝试更新匹配moduleId的数组元素,若未找到匹配项则执行新增操作:

const courseId = "6392f2611e7d670eca9712fa";
const newModule = {
  moduleId: 2,
  moduleTitle: "Module Title 3",
  moduleDescription: "Module 3 description",
  totalSessions: 8,
};

// 第一步:尝试更新已有moduleId对应的元素
const updatedCourse = await MasterCourse.findOneAndUpdate(
  { 
    _id: courseId, 
    "courseModules.moduleId": newModule.moduleId 
  },
  {
    $set: {
      "courseModules.$.moduleTitle": newModule.moduleTitle,
      "courseModules.$.moduleDescription": newModule.moduleDescription,
      "courseModules.$.totalSessions": newModule.totalSessions,
    },
  },
  { new: true } // 返回更新后的完整文档
);

if (!updatedCourse) {
  // 未找到匹配元素,执行新增
  const addedCourse = await MasterCourse.findOneAndUpdate(
    { _id: courseId },
    { $push: { courseModules: newModule } },
    { new: true }
  );
  console.log(addedCourse.courseModules); // 输出更新后的数组
} else {
  console.log(updatedCourse.courseModules); // 输出更新后的数组
}

方案二:原子性聚合管道更新(推荐,支持高并发)

利用MongoDB 4.2+支持的聚合管道更新,通过一次原子操作完成“更新/新增”逻辑,避免并发冲突:

const courseId = "6392f2611e7d670eca9712fa";
const newModule = {
  moduleId: 2,
  moduleTitle: "Module Title 3",
  moduleDescription: "Module 3 description",
  totalSessions: 8,
};

const finalUpdatedCourse = await MasterCourse.findOneAndUpdate(
  { _id: courseId },
  [
    {
      $set: {
        courseModules: {
          $cond: {
            // 判断当前数组中是否存在目标moduleId
            if: { $in: [newModule.moduleId, "$courseModules.moduleId"] },
            // 存在则遍历数组,更新匹配的元素
            then: {
              $map: {
                input: "$courseModules",
                as: "module",
                in: {
                  $cond: {
                    if: { $eq: ["$$module.moduleId", newModule.moduleId] },
                    then: newModule,
                    else: "$$module",
                  },
                },
              },
            },
            // 不存在则将新元素追加到数组末尾
            else: { $concatArrays: ["$courseModules", [newModule]] },
          },
        },
      },
    },
  ],
  { new: true }
);

console.log(finalUpdatedCourse.courseModules); // 输出更新后的数组

注意事项

  • 若你的courseModules子文档需要自动生成_id,Mongoose会默认添加;若不需要,可在Schema中配置courseModules: [{ type: ModuleSchema, _id: false }]。
  • 方案二要求MongoDB版本≥4.2,同时Mongoose版本需支持对应语法(建议使用5.10+版本)。

内容的提问来源于stack exchange,提问作者Ankit Kumar

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 12:15:37