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
相关产品推荐
相关产品推荐

