Mongoose中如何对populated关联字段coinId设置查询筛选条件
问题原因说明
- 初始写法不生效的原因:
find方法的查询条件仅作用于当前signalModel对应的集合,你写的'coinId.Price'是尝试查询Signal集合文档下嵌套的coinId对象的Price字段,但Signal集合里的coinId仅存储关联Coin文档的_id字段,不存在Price属性,所以条件永远无法匹配。 - 聚合查询返回coin为空的原因:
$lookup的from参数需要填写MongoDB数据库中实际的集合名称,Mongoose默认会将模型名转为小写复数作为集合名,比如Coin模型对应的集合名默认是coins,你填的'Coin'和实际集合名不匹配,导致关联失败返回空数组。
正确实现方案
方案1:使用Mongoose populate 带条件过滤
这种写法贴合Mongoose常用语法,适合简单关联查询场景:
signalModel .find() // 关联coinId,仅匹配Price大于1000的Coin文档 .populate({ path: 'coinId', match: { Price: { $gt: 1000 } } }) .exec((err, signals) => { if (err) throw err // 过滤掉关联coinId为null的文档(即不满足Price条件的Signal) const filteredSignals = signals.filter(item => item.coinId !== null) res.json(filteredSignals) })
方案2:修正后的聚合查询
如果偏好原生MongoDB聚合语法,仅需要修正from参数即可:
let signals = await signalModel.aggregate([ { $lookup: { from: 'coins', // 替换为实际的Coin集合名,默认是模型名的小写复数 localField: 'coinId', foreignField: '_id', as: 'coin' } }, { $match: { type: req.query.type ?? /^(buy|sell)$/i, 'coin.Price': { $gt: 1000 } } }, // 可选配置:如果不想让coin是数组格式,可通过$unwind转为对象 { $unwind: '$coin' } ])
如果你在Coin模型中自定义了集合名称,直接取模型中collection配置项的值填入from参数即可。
内容的提问来源于stack exchange,提问作者Mohammad
相关产品推荐
相关产品推荐

