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

如何在Mongoose中实现葡萄酒查询的年份/价格过滤且默认返回全量数据?

问题分析与优化方案

你的需求是为葡萄酒API添加年份、价格过滤功能,同时保证未指定这些参数时不会返回空数组,现有实现尚未完成目标逻辑,且当前写法并非最优方案,下面是具体分析和优化代码:

现有代码的不足

  1. 未实现年份、价格的过滤逻辑,相关代码处于注释状态
  2. 链式调用.where()的方式不够灵活:如果直接启用年份过滤的注释代码,当year参数未指定时,parseInt(year)会得到NaN,.equals(NaN)会导致查询不到任何数据,直接返回空数组,违反需求
  3. 参数类型处理不严谨:page和limit从req.query获取的是字符串,后续计算skip时才转换,容易出现隐式类型转换错误

优化后的实现代码

getWines: async (req, res) => {
  try {
    const types = ['red', 'white'];
    // 提前转换参数类型,默认值设置更严谨
    const {
      limit = 10,
      page = 1,
      search = '',
      type = 'all',
      year,
      price
    } = req.query;
    
    const pageNum = parseInt(page);
    const limitNum = parseInt(limit);
    
    // 校验页码有效性
    if (pageNum <= 0 || isNaN(pageNum)) {
      return res.status(400).json({ error: 'Invalid page number' });
    }
    if (limitNum <= 0 || isNaN(limitNum)) {
      return res.status(400).json({ error: 'Invalid limit number' });
    }

    // 动态构建查询条件,仅在参数有效时添加过滤规则
    const query = {
      name: { $regex: search, $options: 'i' }
    };

    // 处理类型过滤
    if (type !== 'all') {
      query.type = type;
    } else {
      query.type = { $in: types };
    }

    // 处理年份过滤:仅当year存在且为有效数字时添加
    if (year) {
      const yearNum = parseInt(year);
      if (!isNaN(yearNum)) {
        query.year = yearNum;
      }
    }

    // 处理价格过滤:仅当price存在且为有效数字时添加
    if (price) {
      const priceNum = parseInt(price);
      if (!isNaN(priceNum)) {
        query.price = priceNum;
      }
    }

    // 执行查询
    const wines = await Wine.find(query)
      .limit(limitNum)
      .skip((pageNum - 1) * limitNum);

    res.json(wines);
  } catch (error) {
    console.error(error);
    res.status(500).json({ error: 'Internal server error' });
  }
}

优化点说明

  1. 动态构建查询对象:通过query对象按需添加过滤条件,避免了链式调用在参数缺失时的错误逻辑,保证未指定年份/价格时不会添加无效过滤,自然不会返回空数组
  2. 参数提前校验与转换:提前将page、limit、year、price转换为数字并校验有效性,避免后续计算和查询出错
  3. 更严谨的错误处理:对无效参数返回400状态码,服务器错误返回500状态码,符合RESTful规范
  4. 逻辑更清晰:将不同过滤规则拆分到独立的判断块,代码可读性更高,后续扩展其他过滤条件(比如价格范围、产区)也更方便

需求验证

  • 访问http://localhost:1234/api/wine?year=2010:query中会包含year: 2010,返回2010年的葡萄酒
  • 访问http://localhost:1234/api/wine:query仅包含名称模糊查询和类型全匹配,返回限制10条的全部葡萄酒
  • 未指定年份/价格时,不会添加对应过滤条件,只要数据库有数据就不会返回空数组

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 20:10:48