如何将子文档的数据添加到父文档(使用猫鼬)?

How do I add a subdocument's data to a parent document (using mongoose)?

我正在创建一个 MERN 应用程序并有一系列连接的猫鼬模式。

层次结构为:计划 -> 锻炼 -> 锻炼 -> 设置

以下是每个 Schema 的模型代码:

程序架构

const programSchema = mongoose.Schema({

program_name:{
    type: String,
},
workouts:[{
    type: mongoose.Types.ObjectId,
    ref: 'Workout'
}]

锻炼方案

const workoutSchema = mongoose.Schema({
workout_name:{
    type:String
},
exercises: [{
    type: mongoose.Types.ObjectId,
    ref: 'Exercise'
}]

练习图

const exerciseSchema = mongoose.Schema({
exercise_name:{
    type:String
},
notes:{
    type:String
},
sets:[{
    type: mongoose.Types.ObjectId,
    ref: 'Set'
}]

设置架构

const setSchema = mongoose.Schema({
weight:{
    type: String
},
repetitions:{
    type: String
},
rpe:{
    type: String
}

我的问题是,既然它们都是分开的。我如何 link 一个特定的练习集?或锻炼的特定练习?等。我如何将它们相互引用,以便我可以创建一个包含各种锻炼的完整程序,并且每个锻炼都有各种练习等。 我将不胜感激任何智慧。谢谢

有关更多信息,请查看控制器。

程序控制器(创建新程序)

const createProgram = async (req, res) => {

//const {program_name, workouts} = req.body

try {
    const program = new Program(req.body) // create a new program with the information requested
    await program.save() // save it to database
    res.status(201).send(program) // send it back to user
} catch (e) {
    res.status(500).send(e)
}

锻炼控制器(创建新锻炼)

const createWorkout = async (req, res) => {

const {workout_name} = req.body

try {
    const workout = await new Workout({
        workout_name
    })
    await workout.save()
    res.status(201).send(workout)

} catch(e) {
    
}

练习控制器(创建新练习)

const createExercise = async (req, res) => {

const { exercise_name='', notes='', sets } = req.body

try {
    const exercise = await new Exercise({
        exercise_name,
        notes,
        sets
    })
    await exercise.save()
    res.status(201).send(exercise)
} catch (e) {
    console.log(e)
}

设置控制器(创建新设置)

const createSet = async (req, res) => {
const {repetitions='', weight='', rpe=''} = req.body
try {
    const set = await new Set({
        weight,
        repetitions,
        rpe
    })
    await set.save()
    res.status(201).send(set)
} catch (e) {
    res.status(500).send(e)
}

我这样做的方法是在保存时将 id 添加到属性数组。所以我会给你一个路由器的例子,然后希望你能理解足够的东西来做剩下的事情。

对于锻炼,您想在创建程序时将其添加到程序中。所以当你创建它时,只需将id添加到你想要添加它的程序中。

像这样:

const {workout_name} = req.body

try {
    const newWorkout = await Workout.create({
        workout_name
    })

    Program.updateOne(
      { _id: req.params.ProgramId },
      { $addToSet: { workouts: newWorkout._id }},
    )
    
    res.status(201).send(workout)

} catch(e) {
    
}

所以基本上在创建锻炼后,您将该锻炼 ID 添加到父对象的锻炼数组中。您会对其余的路由器执行相同的操作。