Mongoose更新数组内指定对象:添加子对象失败排查
解决Mongoose findOneAndUpdate无法向数组内指定对象添加子对象的问题
问题场景
尝试在Program文档的exercices数组中,给指定exercice ID的对象添加result子对象,但执行findOneAndUpdate查询后无任何效果(无报错)。
现有模型结构
[ { "_id": "634c0777427df2a5adc17b4c", "title": "PROGRAMME TEST", "user": { "name": "Jérémy", "email": "test@gmail.com", "profilPicture": "google.fr" }, "exercices": [ { "exercice": "6349563c2e0df123096b7feb", "totalSet": 1, "rest": "1" // 需要在此处添加result子对象 }, { "exercice": "634956452e0df123096b7fed", "totalSet": 2, "rest": "2" } ] } ]
原查询代码
return this.programModel.findOneAndUpdate( { $and: [ {_id: '634c0777427df2a5adc17b4c' }, // program id { exercices: { 'exercices.exercice': "6349563c2e0df123096b7feb" } }, // 目标exercice id ] }, { $push: {"exercices.exercice": {result: result}}}, { new: true } );
现有Program实体定义(NestJS)
export type ProgramDocument = Program & Document class Exercices { @Prop({ type: mongoose.Schema.Types.ObjectId, ref: 'Exercice' }) exercice: Exercice // 其他@Prop字段 @Prop({ type: mongoose.Schema.Types.Array}) result: Array<ExerciceResult> } class ExerciceResult { @Prop() set: number; @Prop() kilogram: string; } @Schema() export class Program { // 其他@Prop字段 @Prop({ type: mongoose.Schema.Types.Array}) exercices: Array<Exercices> } export const ProgramSchema = SchemaFactory.createForClass(Program)
解决方案
1. 修正查询条件
原查询条件中定位数组元素的方式错误,无需嵌套exercices对象,直接使用数组字段的嵌套路径即可,同时$and可省略(多条件默认逻辑与):
{ _id: '634c0777427df2a5adc17b4c', "exercices.exercice": "6349563c2e0df123096b7feb" }
2. 修正更新路径
使用**位置操作符$**匹配查询到的数组元素,将result对象push到该元素的result数组中,更新操作的路径应为"exercices.$.result":
{ $push: {"exercices.$.result": result} }
3. 优化实体定义(可选)
嵌套类的数组字段无需显式指定mongoose.Schema.Types.Array,NestJS会自动推断类型,修正后的实体定义更简洁:
export type ProgramDocument = Program & Document class ExerciceResult { @Prop() set: number; @Prop() kilogram: string; } class Exercices { @Prop({ type: mongoose.Schema.Types.ObjectId, ref: 'Exercice' }) exercice: Exercice // 其他@Prop字段 @Prop() result: ExerciceResult[] } @Schema() export class Program { // 其他@Prop字段 @Prop({ type: [Exercices] }) exercices: Exercices[] } export const ProgramSchema = SchemaFactory.createForClass(Program)
最终修正后的查询代码
return this.programModel.findOneAndUpdate( { _id: '634c0777427df2a5adc17b4c', "exercices.exercice": "6349563c2e0df123096b7feb" }, { $push: {"exercices.$.result": result} }, { new: true, runValidators: true } // 建议加上runValidators确保字段验证生效 );
内容的提问来源于stack exchange,提问作者jeyremd
相关产品推荐
相关产品推荐

