Mongoose嵌套$lookup查询返回floorports空数组问题排查求解
问题定位与解决方案
核心问题原因
1. 集合名不匹配(90%概率触发)
MongoDB的$lookup的from字段严格匹配数据库中的集合名称,Mongoose注册模型时默认会将模型名转为小写复数作为集合名,你需要先确认:
- 你注册
floorPortSchema对应的模型名如果是FloorPort,默认集合名为floorports,和你代码中写的一致,没问题 - 如果你注册模型时自定义了集合名,或者模型名不是
FloorPort,请把from字段的值改为和数据库中实际集合名完全一致(大小写敏感)
2. 缺少device层级的关联查询
你当前的查询只关联到了floorports层级,floorports下的device字段还是ObjectId类型,没有关联device表,无法得到你期望的展开后的device对象结构。
3. 数据校验问题
如果集合名确认无误,请先取任意一个返回的suite的_id值,在MongoDB shell执行查询db.floorports.find({suite: ObjectId("对应suite的_id值")}),确认该suite下确实存在关联的floorport数据,排除数据本身为空的问题。
修正后的完整聚合查询代码
Client.aggregate([ { $match: { _id: mongoose.Types.ObjectId(clientId), }, }, { $lookup: { from: 'suites', let: { suites: '$suites' }, pipeline: [ { $match: { $expr: { $in: ['$_id', '$$suites'] } }, }, { $lookup: { from: 'floorports', // 请再次确认和数据库实际集合名完全一致 let: { suiteId: '$_id' }, pipeline: [ { $match: { $expr: { $eq: ['$suite', '$$suiteId'] } } }, // 新增device层级的关联查询 { $lookup: { from: 'devices', // device模型名如果是Device,默认集合名就是devices localField: 'device', foreignField: '_id', as: 'device' } }, // 每个floorport仅对应一个device,把数组转为单个对象 { $unwind: '$device' } ], as: 'floorports', }, }, ], as: 'suites', }, }, ])
内容的提问来源于stack exchange,提问作者Jakub Koudela
相关产品推荐
相关产品推荐

