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

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

问题描述

我正在使用 MongoDB 数据库,其集合模型 classesstudentssubjects 和 [academic] performance时间>.以下是基于 Mongoose 的架构和模型:

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

class 集合的文档是最复杂的;一个示例文档是:

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

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

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:

  • 检索所有学生或特定学生的分数(检索 scores 数组中的特定元素)
  • 添加/更新/删除特定学生的分数,针对特定科目(在更新或删除的情况下,检索 scores[n].performance 数组中的特定元素;对于添加,追加到同一个数组.
  • 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

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

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

希望对你有帮助

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

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