MongoDB聚合查询:多级Unwind与Group后关联Users集合
解决方案
你可以在现有聚合流程中,在获取到Evidences数据后,添加关联Users的步骤,具体需要对entriesimages.evidences数组进行展开、关联用户、重新聚合的操作,修改后的完整聚合查询如下:
var entries = await Entries.aggregate([ { $match: { criteria: criteria._id, report: report._id } }, { $lookup: { from: 'entriesimages', localField: '_id', foreignField: 'entry_id', as: 'entriesimages', } }, { $unwind: { path: '$entriesimages', preserveNullAndEmptyArrays: true } }, { $lookup: { from: 'evidences', localField: 'entriesimages._id', foreignField: 'entriesImage_id', as: 'entriesimages.evidences', } }, // 展开evidences数组,保留空数组情况 { $unwind: { path: '$entriesimages.evidences', preserveNullAndEmptyArrays: true } }, // 关联Users集合,将用户信息注入到对应的evidence中 { $lookup: { from: 'users', localField: 'entriesimages.evidences.user_id', foreignField: '_id', as: 'entriesimages.evidences.user', } }, // 将单个user对象从数组转为对象(lookup返回的是数组) { $set: { 'entriesimages.evidences.user': { $first: '$entriesimages.evidences.user' } } }, // 重新聚合evidences数组,按entriesimages的_id分组 { $group: { _id: { entry_id: '$_id', entriesimage_id: '$entriesimages._id' }, entry: { $first: '$$ROOT' }, evidences: { $push: '$entriesimages.evidences' } } }, // 合并回entriesimages结构 { $set: { 'entry.entriesimages.evidences': '$evidences' } }, // 聚合entriesimages数组到对应的entry下 { $group: { _id: '$_id.entry_id', entry: { $first: '$entry' }, entriesimages: { $push: '$entry.entriesimages' }, } }, { $replaceRoot: { newRoot: { $mergeObjects: ['$entry', { entriesimages: '$entriesimages' }] } } }, ]);
关键步骤说明
- 展开evidences数组:使用
$unwind展开entriesimages.evidences,确保每条evidence都能单独关联用户,preserveNullAndEmptyArrays保证没有evidences的条目不会被过滤。 - 关联Users集合:通过
$lookup根据evidences.user_id匹配users._id,将用户数据存入evidences.user数组。 - 转换用户数组为对象:因为
$lookup返回的是数组,用$set配合$first提取数组中的唯一用户对象,简化结构。 - 重新聚合evidences:按
entry_id和entriesimage_id分组,将处理后的evidence重新组合为数组,恢复原来的嵌套结构。 - 恢复entriesimages数组:再次分组将entriesimages聚合到对应的entry下,保持最终数据结构与原查询一致。
内容的提问来源于stack exchange,提问作者Muaaz Khalid
相关产品推荐
相关产品推荐

