I have the following schema for a grid (evaluation grid). Grid => Sections => Criteria => Levels and I want to update a single Level element.
const mongoose = require("mongoose");
const levelSchema = mongoose.Schema(
{
title: {
type: String,
required: true,
},
value: {
type: Number,
required: true,
},
},
{ timestamps: true }
);
exports.Level = mongoose.model("Level", levelSchema);
const criterionSchema = mongoose.Schema(
{
title: {
type: String,
required: true,
},
levels: [levelSchema],
},
{ timestamps: true }
);
criterionSchema.virtual("weight").get(function () {
return Math.max(this.levels.map((level) => level.weigth));
});
exports.Criterion = mongoose.model("Criterion", criterionSchema);
const sectionSchema = mongoose.Schema(
{
name: {
type: String,
required: true,
},
criteria: [criterionSchema],
},
{ timestamps: true }
);
sectionSchema.virtual("weight").get(function () {
return this.criteria.reduce((acc, criteria) => acc + criteria.weight, 0);
});
exports.Section = mongoose.model("Section", sectionSchema);
const schema = mongoose.Schema(
{
name: {
type: String,
required: true,
},
sections: [sectionSchema],
code: { type: Number, required: true },
course: {
type: mongoose.Schema.Types.ObjectId,
ref: "Course",
required: true,
},
},
{ timestamps: true }
);
schema.virtual("weight").get(function () {
return this.sections.reduce((acc, section) => acc + section.weight, 0);
});
exports.Grid = mongoose.model("Grid", schema);
I was able to retrieve a specific Level's Grid with this code :
Grid.findOne({"sections.criteria.levels._id": levelId})
So I tried FindOneAndUpdate with this code :
const grid = await Grid.findOneAndUpdate(
{ "sections.criteria.levels._id": req.params.levelId },
{
$set: {
"sections.$[].criteria.$[].levels.$[].title": req.body.title,
},
},
{ new: true });
But, it changed ALL the Levels of the grid.
How can we update a single Level sub, sub, sub document and returns it ?