Mongoose populate查询match条件中如何自引用同层级数组元素字段
解决方案
你需要的同层级字段引用无法直接在普通populate的match参数中实现,Mongoose的populate match上下文不支持动态引用父级文档的字段,可选择以下两种方案实现需求:
方案1:使用聚合管道(推荐,性能更优)
通过MongoDB原生的聚合查询搭配$lookup操作符,可以自定义关联条件,直接引用同层级的series._id字段:
this.studyModel.aggregate([ // 第一步:匹配目标Study文档 { $match: { _id: mongoose.Types.ObjectId(studyId) } }, // 第二步:展开series数组为单条文档 { $unwind: '$series' }, // 第三步:关联State集合,自定义匹配条件 { $lookup: { from: 'states', // State模型对应的集合名,默认是小写复数形式 let: { seriesId: '$series._id', stateIds: '$series.states', studyId: '$_id' }, pipeline: [ { $match: { $expr: { $and: [ { $eq: ['$studyId', '$$studyId'] }, { $eq: ['$seriesId', '$$seriesId'] }, { $in: ['$_id', '$$stateIds'] } ] } } } ], as: 'series.states' } }, // 第四步:重新合并series为数组 { $group: { _id: '$_id', series: { $push: '$series' } } } ])
方案2:先查询后手动遍历填充(适合小数据量场景)
如果数据量不大,可以先查询到Study数据后,遍历每个series单独填充对应的states:
// 先查询目标Study const study = await this.studyModel.findById(studyId).select('series').lean() // 遍历每个series单独匹配填充states for (const seriesItem of study.series) { seriesItem.states = await State.find({ _id: { $in: seriesItem.states }, studyId: studyId, seriesId: seriesItem._id }) }
额外注意
你原代码中的populate路径存在笔误:Schema中定义的字段是series.states(复数),但你的populate path写的是series.state(单数),调整时需要修正。
内容的提问来源于stack exchange,提问作者Nobita Gascón
相关产品推荐
相关产品推荐

