Mongoose中使用populate+match无返回结果的问题求助
解决Mongoose 4.x中Populate结合Match无返回结果的问题
我来帮你排查下这个问题~结合你的代码和Mongoose 4.13.12的特性,主要有几个可能的原因和对应的解决方案:
1. 先检查拼写错误
看你的代码里有两处明显的拼写问题,这大概率是导致匹配失败的直接原因:
select: 'name pricessss'里的pricessss应该是prices(多打了一个s)match: { name: { $eq: 'someting' }}里的someting应该是something(少了一个h)
先修正这些拼写错误,再运行试试,修正后的代码如下:
let populateQuery = [ { path: 'service', select: 'name prices', // 修正字段拼写 match: { name: { $eq: 'something' }} // 修正匹配值拼写 }, { path: 'job', select: 'appliedUser' } ]; models.Project.find() .populate(populateQuery) .exec((err, projects) => { if (err) { console.error(err); return; } console.log(projects); });
2. 理解Mongoose 4.x中Populate Match的特性
这里要注意一个关键细节:Mongoose 4.x的populate中的match只是过滤要填充的子文档,不会过滤主文档。如果某个Project的关联service不满足match条件,那么这个Project的service字段会被设为null,而不是整个Project文档被排除。
如果你期望的是只返回匹配到符合条件service的Project文档,那么用populate是做不到的,需要改用aggregate的$lookup来实现,示例代码如下:
models.Project.aggregate([ // 关联service集合 { $lookup: { from: 'services', // 这里要填Service模型对应的集合名(通常是小写模型名+s) localField: 'service', foreignField: '_id', as: 'service' } }, // 将service数组展开为单个对象(因为$lookup返回的是数组) { $unwind: '$service' }, // 过滤出service.name为something的文档 { $match: { 'service.name': 'something' } }, // 关联job集合 { $lookup: { from: 'jobs', // 同理,填Job模型对应的集合名 localField: 'job', foreignField: '_id', as: 'job' } }, { $unwind: '$job' }, // 选择需要返回的字段 { $project: { // 这里可以根据你的需求选择Project本身的字段,以及关联字段 _id: 1, // 假设Project有title字段,示例添加 title: 1, 'service.name': 1, 'service.prices': 1, 'job.appliedUser': 1 } } ]).exec((err, filteredProjects) => { if (err) { console.error(err); return; } console.log(filteredProjects); });
额外排查点
- 确认Project模型中的
service字段是ObjectId类型,并且正确关联到了Service模型 - 确认Service集合中确实存在
name为something的文档 - Mongoose 4.13.12是比较旧的版本,如果后续有条件,建议升级到5.x或更高版本,新版本对populate的match支持更完善,也能避免一些老版本的bug
内容的提问来源于stack exchange,提问作者akash kumar
相关产品推荐
相关产品推荐

