я работаю с базой данных MongoDB, чьи коллекции модели классов, студентами, предметами и [академическая] производительностью. Ниже на основе схемы и Mongoose модели:Как обновить MongoDB документы с массивами поддокументов
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
});
};
});
Но как добавить/обновить/удалить эта особенность студента? Мне нужно, чтобы иметь возможность взаимодействовать с class
коллекции следующими способами:
- Retrieve баллов для всех студентов, либо для конкретного студента (извлечения конкретного элемента в
scores
массиве) - Добавить/обновить/удалить счет конкретного студента, для конкретного субъекта (в случае обновления или удаления, получения определенного элемента в
scores[n].performance
массиве, для добавления, добавляемых в том же массиве
Прежде всего, первая часть вашего ответа работал просто отлично. Я не совсем понимаю, как 'populate ('scores.studentId')' получает результаты для каждого ученика; кажется очень мощным. У меня есть некоторые вопросы: (а) как я могу получить оценку конкретного предмета для одного ученика? (b) Как добавить нового ученика в массив 'score? 'с пустым массивом' performance'? (c) Как добавить производительность для одного предмета для конкретного ученика? (d) и (e) аналогичны (b) и (c), но удаляются вместо добавления. Вы дали мне представление о том, как обновлять. Спасибо вам за помощь! –
Не стоит беспокоиться о том, чтобы помочь. В конце дня минимальный документ, который вы можете вытащить, является классом. Если вы хотите вытащить отдельные поля, вы можете передать их в качестве второго параметра внутри find. findOneAndUpdate (query, {'scores.performance.grade': 1}, function (err) {}). Чтобы добавить баллы, просто используйте оператор «push» внутри модели mongoose, т. Е. Model.scores.push ({studentId: ObjectId ('xxxxxxxxx'), производительность: []}) или использовать поиск и обновление и использовать оператор $ push либо либо второй метод лучше, потому что это атомный. – Tim
Могу ли я использовать populate для разрешения всех ссылок на внешние ключи по всей иерархии, за пределами 'scores.studentId'.Сделав это, я позволил ученику соответствовать ссылке «studentId» и аналогичным образом, я хочу, чтобы весь предметный документ соответствовал массиву 'subjectId' для каждого ученика' performance' массив? Моя цель - получить полностью ненормированный документ 'class', если я могу использовать этот термин в контексте MongoDB! –