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

MongoDB中如何使用变量作为键更新嵌套字典字段?

使用变量作为键更新MongoDB嵌套字典字段的问题及解决方法

问题描述

需要更新MongoDB中User集合的course字段,将变量addName中的课程名称作为course的键,添加包含syllabus字段的子对象,但直接通过字符串拼接生成键名的写法出现语法错误。

数据Schema

const UserSchema = new mongoose.Schema({
    email: String,
    password: {type: String, unique: true, required: true},
    id: mongoose.Schema.Types.ObjectId,
    course: mongoose.Schema.Types.Mixed
});

期望效果

当addName = "Intro to Computer Science"时,更新后的文档结构如下:

{
  "email": "12345@gmail.com",
  ...
  "course": {
     "Intro to Computer Science": {
        "syllabus": ""
      }
  }
}

错误代码及问题

尝试直接在对象字面量中拼接键名,导致语法错误:

app.post("/api/add-course/", (req, res) => {
  const email = req.body.email;
  const addName = req.body.addName;
  console.log(req.body)// assumes that User was registered in `./db.mjs`
  User.updateOne({"email": email}, {'$set': {'course.'+addName: {"syllabus": ""}}},
    ).then(result => {
    res.status(201).json({
        message: "success",
        course: user.course
    })
  }).catch(err => {
    console.log(err),
        res.status(500).json({
            error: err
        });
  });
  console.log(user);
})

语法错误截图

解决方法

方法1:使用ES6计算属性名

通过方括号包裹变量,直接在对象字面量中生成动态键名:

app.post("/api/add-course/", (req, res) => {
  const email = req.body.email;
  const addName = req.body.addName;
  // 用计算属性名构建动态更新字段
  const updateField = {
    [`course.${addName}`]: {"syllabus": ""}
  };

  User.updateOne({"email": email}, {'$set': updateField})
    .then(() => {
      // 重新查询获取更新后的用户数据
      return User.findOne({"email": email});
    })
    .then(user => {
      res.status(201).json({
        message: "success",
        course: user.course
      });
      console.log(user);
    })
    .catch(err => {
      console.log(err);
      res.status(500).json({
        error: err
      });
    });
})

方法2:先拼接键名再赋值

先创建空对象,再将拼接好的键名赋值给对象:

app.post("/api/add-course/", (req, res) => {
  const email = req.body.email;
  const addName = req.body.addName;
  const updateObj = {};
  updateObj[`course.${addName}`] = {"syllabus": ""};

  // 使用findOneAndUpdate直接返回更新后的文档
  User.findOneAndUpdate(
    {"email": email}, 
    {'$set': updateObj},
    {returnDocument: 'after'}
  )
    .then(user => {
      res.status(201).json({
        message: "success",
        course: user.course
      });
      console.log(user);
    })
    .catch(err => {
      console.log(err);
      res.status(500).json({
        error: err
      });
    });
})

补充说明

  • 原代码中updateOne方法仅返回更新结果,不包含更新后的文档,若需获取更新后的数据,建议使用findOneAndUpdate并设置returnDocument: 'after'参数。
  • 计算属性名是ES6特性,Node.js v4及以上版本均支持。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 14:35:22