You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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;
}

关键说明

  1. $lookup集合名:from参数必须是MongoDB中实际存在的集合名称,Mongoose默认会将模型名转为小写复数(比如Game模型对应games集合),如果你的集合名有自定义配置,需要对应修改。
  2. $unwind的作用:$lookup返回的是数组类型结果,而每个Product仅关联一个Game,用$unwind将数组转为单个对象,方便后续筛选操作。
  3. $match过滤逻辑:直接通过gameDetails.status筛选,仅保留关联Game状态为'Y'的Product,彻底排除不符合条件的文档。
  4. $project自定义返回结构:可根据业务需求调整返回字段,比如保留原Product的game字段,或只返回Game的部分信息(如名称、缩略图)。

内容的提问来源于stack exchange,提问作者Random People

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 18:31:04