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

如何在Node.js中为Mongoose设置动态日期键

动态日期作为Mongoose属性名的实现方案

需求说明

需要将Mongoose Schema中的属性名设置为从今日开始的连续动态日期,生成数量为 workout_weeks * 7 个(比如workout_weeks=2时,生成14个连续日期),用户点击指定日期可快速获取对应训练内容。当前代码中所有属性都使用固定的当前日期,需调整为动态连续日期。

现有代码

用户Schema(userSchema)

// 使用moment库
let date = config.moment().format("YYYY-MM-DD");

const userSchema = new mongoose.Schema({
  name: {
    type: String,
  },
  age:{
    type: Number,
  },
  userStream :{ 
    workout: [{
        workout_weeks:{
            type: Number,
        },
        // 注释:按workout_weeks生成对应天数的训练记录,用二维数组存储
        weeks: [            
          [
            {
              [date]: {
                exercises: {
                type: [String],
                }
              }
            }
          ]
        ]
    }]
 }
});

训练计划Schema(workoutSchema)

const workoutSchema = new mongoose.Schema({
  workout_weeks:{
    type: Number,
  },
  [date]: {
    exercises: {
      type: String,
    }
  }
});

用户注册接口(enroll)

export const enroll = async (req, res) => {
  try {
    const { id } = req.params;
    const { workout_id } = req.body;

    const user = await userSchema.findById(id);
    if (!user) {
      return res.status(400).json(errorResponse("User not found"));
    }

    const workout = await workout_id.findById(program_id)

    if (!workout) {
      return res.status(400).json(errorResponse("Workout not found"));
    }

    user.userStream.workout.push(program);

    await user.save();

    return res
      .status(200)
      .json(sucessResponse("User enrolled successfully", user.userStream));
  } catch (error) {
    res
      .status(500)
      .json(errorResponse(error?.message || "Something went wrong"));
  }
};

解决方案

1. 调整Schema结构

Mongoose Schema为静态定义,无法在初始化时生成动态日期键,因此改用Mixed类型存储动态结构,同时优化数据结构以提升日期查询效率:

修改后的userSchema

const userSchema = new mongoose.Schema({
  name: { type: String },
  age: { type: Number },
  userStream: {
    workout: [{
      workout_weeks: { type: Number },
      // 用对象存储,键为日期字符串,值为对应训练内容
      dailyExercises: {
        type: mongoose.Schema.Types.Mixed,
        default: {}
      }
    }]
  }
});

修改后的workoutSchema

const workoutSchema = new mongoose.Schema({
  workout_weeks: { type: Number },
  // 用Mixed类型存储动态日期的训练模板
  dailyTemplates: {
    type: mongoose.Schema.Types.Mixed,
    default: {}
  }
});

2. 修改enroll接口生成动态日期

在用户注册时,根据训练计划的workout_weeks生成从今日开始的连续日期,构建对应的训练结构:

export const enroll = async (req, res) => {
  try {
    const { id } = req.params;
    const { workout_id } = req.body;

    const user = await userSchema.findById(id);
    if (!user) {
      return res.status(400).json(errorResponse("用户不存在"));
    }

    // 修正原代码变量错误:使用workoutSchema查询训练计划
    const workout = await workoutSchema.findById(workout_id);
    if (!workout) {
      return res.status(400).json(errorResponse("训练计划不存在"));
    }

    const totalDays = workout.workout_weeks * 7;
    const dailyExercises = {};
    const today = config.moment();

    // 生成连续日期并初始化训练内容
    for (let i = 0; i < totalDays; i++) {
      const currentDate = today.clone().add(i, 'day').format("YYYY-MM-DD");
      // 若训练计划有对应日期模板则复用,否则初始化空数组
      dailyExercises[currentDate] = {
        exercises: workout.dailyTemplates[currentDate]?.exercises || []
      };
    }

    // 构建要添加的训练项
    const newWorkoutEntry = {
      workout_weeks: workout.workout_weeks,
      dailyExercises
    };

    user.userStream.workout.push(newWorkoutEntry);
    await user.save();

    return res
      .status(200)
      .json(successResponse("用户注册成功", user.userStream));
  } catch (error) {
    res
      .status(500)
      .json(errorResponse(error?.message || "服务器出错"));
  }
};

3. 按日期查询训练内容示例

后续查询指定日期的训练内容时,可直接通过日期键访问:

// 查询2023-07-28的训练内容
const targetDate = "2023-07-28";
const workoutEntry = user.userStream.workout[0]; // 取第一个训练计划
const dayExercises = workoutEntry.dailyExercises[targetDate];

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.15 00:01:30