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

如何为Mongoose实现多条件过滤?游戏商店需新增平台系统过滤

可行实现方案解答

核心结论

不需要必须将platform和system加入tags数组,更推荐独立维护维度+扩展过滤逻辑的方案,既保留数据语义清晰性,又便于后续功能扩展。


方案一:独立扩展过滤逻辑(推荐)

platform(发行平台,如Steam)和system(运行系统,如PC)属于和tags/genres平行的分类维度,单独处理过滤逻辑更合理,具体修改如下:

1. 修改API Controller代码

async get(req, res) {
    try {
        const page = parseInt(req.query.page) - 1 || 0;
        const limit = parseInt(req.query.limit) || 5;
        const search = req.query.search || '';
        let sort = req.query.sort || "top";
        let tags = req.query.tags || 'all';
        // 新增平台和系统的查询参数
        let platforms = req.query.platforms || 'all';
        let systems = req.query.systems || 'all';

        // 用distinct高效获取所有可选维度值(替代原全查循环的低效写法)
        const [tagsOpt, platformOpt, systemOpt] = await Promise.all([
            Games.distinct('tags'),
            Games.distinct('platform'),
            Games.distinct('system')
        ]);

        // 处理各维度参数
        tags === 'all' ? (tags = [...tagsOpt]) : (tags = req.query.tags.split(','));
        platforms === 'all' ? (platforms = [...platformOpt]) : (platforms = req.query.platforms.split(','));
        systems === 'all' ? (systems = [...systemOpt]) : (systems = req.query.systems.split(','));
        
        // 处理排序逻辑(修复原代码的赋值错误)
        req.query.sort ? (sort = req.query.sort.split(',')) : (sort = [sort]);
        let sortBy = {};
        if (sort[1]) {
            sortBy[sort[0]] = sort[1] === 'asc' ? 1 : -1;
        } else {
            sortBy['top'] = -1;
        }

        // 构建复合查询条件
        const query = {
            title: { $regex: search, $options: 'i' },
            tags: { $in: [...tags] }
        };
        // 添加平台过滤
        if (platforms.length > 0 && platforms !== 'all') {
            query.platform = { $in: [...platforms] };
        }
        // 添加系统过滤
        if (systems.length > 0 && systems !== 'all') {
            query.system = { $in: [...systems] };
        }

        // 查询数据
        const gamesData = await Games.find(query)
            .sort(sortBy)
            .skip(page * limit)
            .limit(limit);

        const total = await Games.countDocuments(query);

        const response = {
            error: false,
            total,
            page: page + 1,
            limit,
            tags: tagsOpt,
            platforms: platformOpt, // 返回可选平台列表给前端
            systems: systemOpt,     // 返回可选系统列表给前端
            gamesData
        };
        res.status(200).json(response);
    } catch (error) {
        console.log(error);
        res.status(400).json({ message: 'Ошибка получения' })
    }
}

2. 代码优化说明

  • 用Promise.all结合distinct批量获取所有可选维度值,替代原全量查询游戏再循环的低效逻辑,大幅提升性能
  • 修复了原排序逻辑中的赋值错误(sortBy[sort[0] = sort[1]]是错误写法,改为正确的键值对赋值)
  • 新增返回platforms和systems可选列表,方便前端渲染筛选器选项
  • 各过滤维度独立可控,后续新增其他维度(如价格区间)时可快速扩展

方案二:合并到tags数组(不推荐)

如果想复用现有tags的过滤逻辑,可以在保存游戏数据时,将platform的值和system数组的元素批量加入到tags数组中(例如:game.tags.push(game.platform, ...game.system)),这样无需修改过滤逻辑即可实现平台/系统的筛选。

但该方案存在明显缺点:

  • 数据语义混淆:tags原本是标签维度,混入平台/系统后难以区分,后续维护(如修改平台名称)容易出错
  • 无法单独统计或展示平台/系统维度的信息,限制后续功能扩展

内容的提问来源于stack exchange,提问作者Slow Storm

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 14:55:40