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

MongoDB聚合$match表达式中使用$cond实现可选条件动态查询

MongoDB可选尺码筛选聚合实现方案

核心需求

  • 传入selectedSize参数时,仅返回匹配对应分类、子分类、指定尺码的商品
  • 未传入selectedSize(值为null)时,跳过尺码校验,返回所有匹配分类、子分类的商品

方案1:JS层动态构造匹配条件(优先推荐)

这是生产环境最常用的写法,查询性能最优,可以命中数据库索引,逻辑维护成本低:

// 初始化固定必传的筛选条件
const matchStage = {
  "product.category": req.body.selectedCategory,
  "product.subCategory": req.body.selectedSubCategory
};

// 仅当尺码参数为有效值时,追加尺码过滤规则
if (req.body.selectedSize !== null && req.body.selectedSize !== undefined) {
  matchStage["product.size"] = req.body.selectedSize;
}

// 执行聚合查询
const searchResults = await user.aggregate([
  { $match: matchStage }
  // 后续可追加分页、排序、投影等其他聚合阶段
]);

该方案优势:

  • 避免在聚合表达式中写冗余判断,代码可读性高
  • $match阶段的等值查询条件可以命中集合上的普通索引,大数据量下查询速度远高于$expr写法
  • 不会出现聚合表达式语法写错导致的匹配异常

方案2:聚合管道内写条件判断(仅作语法参考)

如果必须把所有判断逻辑放在聚合管道内部实现,注意$expr下的$cond需要返回布尔值作为匹配依据,不能直接返回查询对象,修正后的代码如下:

const searchResults = await user.aggregate([
  {
    $match: {
      "product.category": req.body.selectedCategory,
      "product.subCategory": req.body.selectedSubCategory,
      $expr: {
        $cond: {
          // 判断是否传入了有效尺码参数
          if: { $ne: [req.body.selectedSize, null] },
          // 传了尺码:校验文档size字段和传入值是否相等,相等则保留文档
          then: { $eq: ["$product.size", req.body.selectedSize] },
          // 没传尺码:直接返回true,所有文档都满足尺码条件
          else: true
        }
      }
    }
  }
]);

原代码错误说明

  • $cond的then/else分支需要返回布尔判断结果,原代码直接写{ product.size: xxx }的对象格式不符合聚合表达式语法
  • 原代码else分支写{ product.size: "" }会强制匹配size为空的商品,完全不符合“跳过尺码筛选”的需求
  • 不要给请求参数强行套模板字符串,否则null值会被转为字符串"null",导致条件判断逻辑失效

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 16:54:36