如何在Mongoose中按关联Game的状态筛选Product文档?
筛选关联Game状态为'Y'的Product文档
你遇到的问题核心在于:populate的match参数仅会过滤填充的关联文档,不会移除主文档(Product),所以不符合条件的Product仍会被返回,只是其game字段为null。要彻底筛选出关联Game状态为'Y'的Product,需要用MongoDB的聚合管道实现,具体步骤如下:
聚合实现代码
import Product from './models/Product'; // 替换为你的Product模型实际路径 async function getProductsWithActiveGame() { const result = await Product.aggregate([ // 第一步:关联Game集合,将匹配的Game数据存入gameDetails数组 { $lookup: { from: 'games', // 注意:这里是MongoDB中Game模型对应的集合名,默认是模型名小写复数 localField: 'game', // Product中关联Game的字段 foreignField: '_id', // Game集合中的主键 as: 'gameDetails' // 存储关联结果的字段名 } }, // 第二步:将数组转为单个对象(每个Product仅关联一个Game) { $unwind: '$gameDetails' }, // 第三步:筛选出Game状态为'Y'的Product { $match: { 'gameDetails.status': 'Y' } }, // 可选:自定义返回字段结构,按需保留或移除字段 { $project: { name: 1, game: '$gameDetails._id', // 保留原Product的game字段(ObjectId) category: 1, slug: 1, image: 1, price: 1, nominal: 1, description: 1, // 如需返回Game的其他信息,可按需添加 gameName: '$gameDetails.name', gameThumbnail: '$gameDetails.thumbnail', createdAt: 1, updatedAt: 1 } } ]); return result; }
关键说明
- $lookup集合名:
from参数必须是MongoDB中实际存在的集合名称,Mongoose默认会将模型名转为小写复数(比如Game模型对应games集合),如果你的集合名有自定义配置,需要对应修改。 - $unwind的作用:
$lookup返回的是数组类型结果,而每个Product仅关联一个Game,用$unwind将数组转为单个对象,方便后续筛选操作。 - $match过滤逻辑:直接通过
gameDetails.status筛选,仅保留关联Game状态为'Y'的Product,彻底排除不符合条件的文档。 - $project自定义返回结构:可根据业务需求调整返回字段,比如保留原Product的
game字段,或只返回Game的部分信息(如名称、缩略图)。
内容的提问来源于stack exchange,提问作者Random People
相关产品推荐
相关产品推荐

