Javascript 我如何使用Express/Mongoose将模型引用到我的用户模型

Javascript 我如何使用Express/Mongoose将模型引用到我的用户模型,javascript,node.js,rest,express,mongoose,Javascript,Node.js,Rest,Express,Mongoose,我有两个模型,一个是我的用户模型,另一个是我的课程模型。我希望这样,当用户(教师)创建课程时,它会将该课程分配给他们,反之亦然。以下是我的模型,可以更好地解释: 课程模式/模式: var CourseSchema = new Schema({ courseID: { type: Number, unique: true }, courseName: String, courseDesc: { type: String

我有两个模型,一个是我的用户模型,另一个是我的课程模型。我希望这样,当用户(教师)创建课程时,它会将该课程分配给他们,反之亦然。以下是我的模型,可以更好地解释:

课程模式/模式:

var CourseSchema = new Schema({
    courseID: {
        type: Number,
        unique: true
    },
    courseName: String,
    courseDesc: {
        type: String,
        default: "No course description provided."
    },
    coursePicture: {
        type: String,
        required: false
    },
    teacher: [
        {
           type: mongoose.Schema.Types.ObjectId,
           ref: 'User'
        }
    ],
    students: [
        {
            type: mongoose.Schema.Types.ObjectId,
            ref: 'Student'
         }
    ]
})
var UserSchema = new mongoose.Schema({  
  firstName: String,
  lastName: String,
  email: String,
  courses: [
    {
       type: mongoose.Schema.Types.ObjectId,
       ref: 'Course'
    }
  ], 
  password: String
});
用户架构/模型:

var CourseSchema = new Schema({
    courseID: {
        type: Number,
        unique: true
    },
    courseName: String,
    courseDesc: {
        type: String,
        default: "No course description provided."
    },
    coursePicture: {
        type: String,
        required: false
    },
    teacher: [
        {
           type: mongoose.Schema.Types.ObjectId,
           ref: 'User'
        }
    ],
    students: [
        {
            type: mongoose.Schema.Types.ObjectId,
            ref: 'Student'
         }
    ]
})
var UserSchema = new mongoose.Schema({  
  firstName: String,
  lastName: String,
  email: String,
  courses: [
    {
       type: mongoose.Schema.Types.ObjectId,
       ref: 'Course'
    }
  ], 
  password: String
});
基本上,我想让它在我的前端,我可以做的事情,如课程。教师。名字或用户。课程。我的模式在两个不同的文件中,但我相信这是好的。这就像在用户创建帖子时为其分配帖子一样。我不知道我怎么能做到这一点,因为我已经尝试了多种方法

现在,我正在创建一个课程

// Creates a new course
router.post('/create', function (req, res) {
    Course.create({
            courseID : req.body.courseID,
            courseName : req.body.courseName,
            courseDesc : req.body.courseDesc,
            coursePicture : req.body.coursePicture,
            teacher : req.body.id,
            students: req.body.students
        }, 
        function (err, course) {
            if (err) return res.status(500).send("There was a problem adding the information to the database.");
            res.status(200).send(course);

        });
});
我已经在该代码所属的控制器中引用了用户模型,因此var User=require(“../User/User”); 我相信这是成功的必要条件。如果你有任何问题,请让我知道,因为我不是最好的解释像这样的事情

希望有人能帮助我


谢谢。

这是一个数据库设计问题。应该只有一个存储课程信息的地方,即课程表和用户表不应该了解课程。应该有一个将课程与用户关联的表:UserCourseRelations表

// Creates a new course
router.post('/create', function (req, res) {
    Course.create({
            courseID : req.body.courseID,
            courseName : req.body.courseName,
            courseDesc : req.body.courseDesc,
            coursePicture : req.body.coursePicture,
            teacher : req.body.id, // find this user
            students: req.body.students,
            attendance: req.body.attendance 
        }, 
        function (err, course) {
            User.findById(req.body.id, function(err, user) {
                user.update({
                    $push: {
                        courses: course._id
                    }
                }, function(err) {
                     if (err) return res.status(500).send("There was a problem adding the information to the database.");
                     res.status(200).send(course);
                })
            })
        });
});
我极力避免存储用户在用户表中相关的CourseID数组,因为这是不必要的耦合,因此不是好的数据库设计。而且,随着每一行上的数组的增长,它会使对用户表的读取陷入停滞

下面是我将如何处理这个问题。请注意,其中一些代码使用ES6语法。以下代码未经测试,但应该可以工作。看一看:

创建CourseSchema和CourseModel

var CourseSchema = new mongoose.Schema({
    courseID: {
        type: Number,
        unique: true
    },
    courseName: String,
    courseDesc: {
        type: String,
        default: "No course description provided."
    },
    teacherId: {
        type: mongoose.Schema.Types.ObjectId,
    }
    coursePicture: {
        type: String,
        required: false
    },
    students: [
        {
            type: mongoose.Schema.Types.ObjectId,
            ref: 'Student'
        }
    ]
})

CourseSchema.statics.createNew = function(data, callback) {
    // do some verification here

    // insert the new course
    return new this(data).save((err, dbCourse) => {
        if (err) {
            return callback(err)
        }

        UserCourseRelationSchema.insertNew('teacher', userId, courseID, (err, dbUserCourseRelation) => {
            if (err) {
                return callback(err)
            }

            // done. return the new course
            callback(null, dbCourse)
        })
    })

    CourseSchema.statics.getByIds = function(courseIDs, callback) {
        // find all of the courses where the courseID is in the courseIDs array
        // see https://docs.mongodb.com/manual/reference/operator/query/in/
        this.find({courseID: {$in: courseIDs}}, (err, courses) => {
            if (err) {
                // something went wrong
                return callback(err)
            }
            callback(null, courses)
        })
    }
}

let CourseModel mongoose.model('courses', CourseSchema);
创建将课程与用户关联的UserCourseRelationSchema和UserCourseRelationModel,反之亦然

var UserCourseRelationSchema = new mongoose.Schema({  
    userId: {
        type: String,
        required: true,
    },
    courseID: {
        type: Number,
        required: true,
    },
    type: {
        type: String,
        enum: ['teacher', 'student'],
        required: true,
    },
});

UserCourseRelationSchema.statics.createNew = function(type, courseID, userId, callback) {
    // do some verification here. I suggest making sure this relation doesn't already exist

    // insert the new course
    return new this({
        courseID: courseID,
        userId: userId,
        type: type,
    }).save((err, dbUserCourseRelation) => {
        if (err) {
            return callback(err)
        }

        // return the new relation
        callback(null, dbRelation)
    })
}

UserCourseRelationSchema.statics.getTeacherRelationCourseIdsByUserId = function(userId, callback) {
    let query = this.find({userId: userId, type: 'teacher'})
    query.distinct('courseID') // get an array of only the distinct courseIDs
    query.exec((err, courseIDs) => {
        if (err) {
            // something went wrong
            return callback(err)
        }
        callback(null, courseIDs)
    })
}

let UserCourseRelationModel = mongoose.model('user_course_relations', UserCourseRelationSchema);
创建UserSchema和UserModel

var UserSchema = new mongoose.Schema({  
    firstName: String,
    lastName: String,
    email: String,
    password: String
});

UserSchema.statics.getAllCoursesById = function(userId, callback) {
    // get the relations for the courses the user is a teacher of
    UserCourseRelationModel.getTeacherRelationCourseIdsByUserId(userId, (err, courseIDs) => {
        // get the courses by the returned coursIDs
        CourseModel.getByIds(courseIDs, (err, courses) => {
            if (err) {
                // something went wrong
                return callback(err)
            }
            callback(nul, courses)
        })
    })
}

let UserModel = mongoose.model('users', UserSchema);

// -- create the router

// Creates a new course
router.post('/create', function (req, res) {
    CourseModel.createNew({
        courseID : req.body.courseID,
        courseName : req.body.courseName,
        courseDesc : req.body.courseDesc,
        coursePicture : req.body.coursePicture,
        teacher : req.body.id,
        students: req.body.students
    }, function (err, course) {
        if (err) return res.status(500).send("There was a problem adding the information to the database.");
        res.status(200).send(course);
    });
});

 // -- done

我还建议尽可能使用承诺,因为它使所有这些逻辑更加简单。

那么问题出在哪里?对不起,我可能应该重新措辞。我没有问题,我只是不知道如何将课程链接到用户(教师)并将用户(教师)链接到课程,以便使用帖子中提到的字段:Course.Teacher.firstName或User.courses这是一个好问题。我在下面的回答中提供了一个全面的答案,其中包括一些数据库设计技巧。我尝试了这个方法,它确实有效,但与我想做的不同,因为我想引用user.courses.courseName或其他内容。这只是放置ID,我认为让它发送整个课程对象不是最好的主意。Mongodb是noSql数据库,它没有关系,但有子文档!谢谢你的回复。我不熟悉ES6语法,实际上我是一个学习Node/Express/Mongoose的初学者。为了实现我的目标,这些改变真的是必要的吗?我正在看这个,我觉得所有这些改变都不是真的需要。虽然我不是专家,但很难理解您所做的一切。@medtleukiliuly“关系”不是sql保留的概念。关系是你可以随心所欲地实现的东西。我在回答中展示的是实现关系的一种方法。这是数据库设计问题,而不是技术问题。正如我所说的,如果您继续大量耦合表,查询将变得越来越昂贵。@omar这些更改是没有必要的,但如果您不想在不久的将来碰壁,我强烈建议他们。这里唯一的新语法是箭头函数()=>和解构赋值。您的服务器应该有ES6,但如果它不让我知道,我可以为您调整答案中的语法。@lwdthe1我将不胜感激。您是否有意见分歧或其他问题,以便我们可以聊天,以便我可以与您进行更多讨论,因为我仍然有一些关于这方面的问题