如何用子文档数组更新MongoDB文档 [英] How to update MongoDB documents with arrays of sub-documents

查看:167
本文介绍了如何用子文档数组更新MongoDB文档的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用一个MongoDB数据库,这个数据库的集合模型 class EM>。下面是基于Mongoose的模式和模型:

  var mongoose = require('mongoose'); 
var Schema = mongoose.Schema;
var ObjectId = Schema.Types.ObjectId;

// SUBJECT collection
var subjectSchema = new Schema({$ b $ name:{type:String,required:true},
category:{type:String, required:true}
});
var Subject = mongoose.model('Subject',subjectSchema);

学生集合
var studentSchema =新模式({
name:{type:String,required:true},
grade:{type:Number, required:true}
});
var Student = mongoose.model('Student',studentSchema);
$ b $ // 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);
$ b $ // *注意*:这只是用作子文档模式,而不是作为集合
var classStudentSchema = new Schema({
studentId:{type :ObjectId,ref:Student.modelName,required:true},
performance:[performanceSchema]
},{_id:false});

CLASS集合
var classSchema =新架构({
name:{type:String,required:true},
scores [classStudentSchema]
});
var Class = mongoose.model('Class',classSchema);

class 集合的文档是最复杂的地段一个示例文件是:

  {
_id:ObjectId(57758f15f68da08c254ebee1),
name:Grade 5 - Section A,
scores:[{$ b $studentId:ObjectId(5776bd36ffc8227405d364d2),
performance bsubjectId: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
}]
}]
}

我可以使用下面的代码检索现有的类文档并添加学生分数:


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

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


  • 检索所有学生或特定学生的分数(检索分数数组中的特定元素)
  • 添加/更新/删除特定学生的分数,对于特定的主题(在更新或删除的情况下,检索 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 is ObjectStudent
    //因此,所有学生的所有分数
    });

    添加/更新/删除特定学生的分数更新或删除,检索scores [n] .performance数组中的特定元素;添加,附加到同一个数组。 code> Class.findOneAndUpdate({name:'Grade 5 - Section A'
    ,'scores.studentId':ObjectId('5776bd36ffc8227405d364d2')
    ,'scores.performance.subjectId':ObjectId ($ 57
    $ {$ set: b});

    我希望有帮助


    I am working with a MongoDB database whose collections model classes, students, subjects, and [academic] performance. Below are the Mongoose based schema and models:

    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);
    

    The class collection's documents are the most complex of the lot; an example document would be:

    {
      "_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"
        }]
      }]
    }
    

    I was able to retrieve an existing class document and add a student to it's scores using the following code:

    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
        });
      };
    });
    

    But how do I add/update/delete that particular student's performance? I need to be able to interact with the class collection in the following ways:

    • Retrieve the scores for all students, or for a specific student (retrieve specific element in the scores array)
    • Add/ update/ delete a specific student's score, for a specific subject (in case of update or delete, retrieve a specific element in the scores[n].performance array; for add, append to the same array.

    解决方案

    There are a few way to do this I'll answer point by point

    Retrieve the scores for all students, or for a specific student (retrieve specific element in the scores array)

    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
    });
    

    Add/ update/ delete a specific student's score, for a specific subject (in case of update or delete, retrieve a specific element in the scores[n].performance array; for add, append to the same array.

    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
        });
    

    I hope that helps

    这篇关于如何用子文档数组更新MongoDB文档的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆