Mongoose如何动态更新数组中嵌套对象的指定字段值
问题排查与修复方案
1. 修复Schema语法错误
你提供的Schema存在括号不匹配的语法问题,同时如果需要支持动态星期字段(比如tuesday、wednesday等),可以调整为以下写法:
const mongoose = require("mongoose"); const { ObjectId } = mongoose.Schema; const carersSchema = new mongoose.Schema({ // 补充你实际的用户id字段,这里假设字段名为userId userId: ObjectId, rosters: [ { _id: ObjectId, schedule: { monday: { start: String, finish: String, notes: String }, tuesday: { start: String, finish: String, notes: String }, // 其他星期字段同理补充,若不需要提前定义所有星期,可以直接把schedule类型设为Schema.Types.Mixed } } ] }, { // 如果schedule下的字段是动态新增、未提前定义,需要关闭严格模式避免字段被Mongoose拦截 strict: false }); module.exports = mongoose.model("Carers", carersSchema);
2. 修复更新逻辑错误
你的更新路径多余使用了数组定位符$,$仅用于定位数组中匹配的元素,schedule和星期字段都是普通对象,不需要加$,同时查询条件要补上用户id匹配,避免改错其他用户的文档:
exports.updateRoster = (req, res) => { const editDay = req.body.day; const value = req.body.valueOfEntry; const userId = req.body.id; const rosterId = req.body.rosterId; const startPerieod = req.body.time; // 构造正确的动态更新路径,仅rosters数组需要用$定位匹配元素 const updateKey = `rosters.$.schedule.${editDay}.${startPerieod}`; const dynObj = { [updateKey]: value }; // 查询条件同时匹配用户id和roster的_id,定位更精准 // 注意模型名要和导出的一致,你导出的模型名为Carers,此处不要写错 Carers.updateOne( { userId: userId, "rosters._id": rosterId }, { $set: dynObj } ).exec((err, result) => { if (err) { return res.status(400).json({ error: err }); } res.json(result); }); };
可选优化说明
如果你的schedule字段下的星期是完全动态新增的,建议把schema中schedule的类型设置为Schema.Types.Mixed,避免Mongoose的严格校验自动过滤未提前定义的字段。
内容的提问来源于stack exchange,提问作者Brendan Little
相关产品推荐
相关产品推荐

