如何用子文档数组更新MongoDB文档

我正在使用一个MongoDB数据库,这个数据库的集合模型学生主题和学术performance 。 下面是基于Mongoose的模式和模型:

var mongoose = require('mongoose'); var Schema = mongoose.Schema; var ObjectId = Schema.Types.ObjectId; // SUBJECT collection var subjectSchema = new Schema({ name : { type: String, required: true }, category : { type: String, required: true } }); var Subject = mongoose.model('Subject', subjectSchema); // STUDENT collection var studentSchema = new Schema({ name : { type: String, required: true }, grade : { type: Number, required: true } }); var Student = mongoose.model('Student', studentSchema); // PERFORMANCE collection var performanceSchema = new Schema({ subjectId : { type: ObjectId, ref: Subject.modelName, required: true }, score : { type: Number, required: true }, maximum : { type: Number, required: true }, grade : { type: String, required: true } }); var Performance = mongoose.model('Performance', performanceSchema); // *Note*: This is just to use as a sub-document schema, and not as a collection var classStudentSchema = new Schema({ studentId : { type: ObjectId, ref: Student.modelName, required: true }, performance : [performanceSchema] }, { _id: false }); // CLASS collection var classSchema = new Schema({ name : { type: String, required: true }, scores : [classStudentSchema] }); var Class = mongoose.model('Class', classSchema); 

class资料是最复杂的, 示例文档将是:

 { "_id" : ObjectId("57758f15f68da08c254ebee1"), "name" : "Grade 5 - Section A", "scores" : [{ "studentId" : ObjectId("5776bd36ffc8227405d364d2"), "performance": [{ "subjectId" : ObjectId("577694ecbf6f3a781759c54a"), "score" : 86, "maximum" : 100, "grade" : "B+" }, { "subjectId" : ObjectId("5776ffe1804540e29c602a62"), "score" : 74, "maximum" : 100, "grade" : "A-" }] }, { "studentId" : ObjectId("5776bd36ffc8227405d364d5"), "performance": [{ "subjectId" : ObjectId("577694ecbf6f3a781759c54a"), "score" : 94, "maximum" : 100, "grade" : "A" }, { "subjectId" : ObjectId("5776ffe1804540e29c602a62"), "score" : 81, "maximum" : 100, "grade" : "A" }] }] } 

我能够检索一个现有的类文件,并使用下面的代码添加一个学生的分数:

 Class.findOne({ name: 'Grade 5 - Section A' }, function(err, class) { if (err) throw err; Student.findOne({ name: 'John Doe' }, function(err, student) { if (err) throw err; class.scores.push({ studentId: student.id }); }; }); 

但是,如何添加/更新/删除特定学生的performance呢? 我需要能够通过以下方式与class集合进行交互:

  • 检索所有学生或特定学生的scores (检索scores数组中的特定元素)
  • 添加/更新/删除特定学生的分数,对于特定的主题(在更新或删除的情况下,检索scores[n].performance数组中的特定元素;添加,附加到同一个数组。

有几种方法可以做到这一点,我将逐点回答

检索所有学生或特定学生的分数(检索分数数组中的特定元素)

 Class.findOne({ name: 'Grade 5 - Section A'}) .populate('scores.studentId') .exec(function(err, class) { if (err) throw err; //now class.scores.studentId becomes ObjectStudent //hence you have all scores for all students }); 

添加/更新/删除特定学生的分数,对于特定的主题(在更新或删除的情况下,检索score [n] .performance数组中的特定元素;添加,附加到同一个数组。

 Class.findOneAndUpdate({name: 'Grade 5 - Section A' ,'scores.studentId': ObjectId('5776bd36ffc8227405d364d2') , 'scores.performance.subjectId' : ObjectId('577694ecbf6f3a781759c54a')} , {$set: {scores.performance. score: 50}} , function(err, data) { if (err) throw err }); 

我希望有帮助