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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 13:54:04