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

如何在Mongoose聚合函数中实现WHERE IN子句

筛选同时包含多个分类ID的Mongoose文档

问题场景

现有两个Mongoose Product文档,需要筛选出同时包含分类ID 62bacb137e6e0b6ac850b9ce 和 63a7b5bb333394043fdca923 的文档(即文档的category数组必须同时包含这两个ID)。之前尝试的聚合代码未达到预期效果。

错误的聚合代码示例:

const product = await Product.aggregate([
    {
      $match: {
        $text: { $search: `\"${searchText}\"` },
      },
    },
    {
      $addFields: {
        root: "$$ROOT",
      },
    },
    {
      $project: {
        name: "$root.name",
        category: {
          $filter: {
            input: "$root.category",
            as: "category",
            cond: { $in: ["62bacb137e6e0b6ac850b9ce" , "63a7b5bb333394043fdca923"] },
          },
        },
        avgRating: {
          $floor: { $avg: "$ratings.star" },
        },
        price: "$root.price",
        slug: "$root.slug",
        images: "$root.images",
        color: "$root.color",
        description: "$root.description",
        ratings: "$root.ratings",
        sold: "$root.sold",
      },
    },
  ]);

错误原因

这段代码的问题在于:

  1. $filter的作用是过滤数组内的元素,而非筛选整个文档——即使category数组被过滤,不符合条件的文档依然会被保留。
  2. $in的语法使用错误,正确格式应为{ $in: [ <待匹配值>, <数组> ] },参数顺序写反,且$in无法实现"同时包含多个值"的逻辑。

正确实现方法

方法一:使用$match+$all(推荐,性能最优)

直接在聚合的$match阶段用$all运算符筛选文档,$all会匹配数组中同时包含所有指定元素的文档,且能利用category字段的索引提升查询效率。

// 定义需要匹配的分类ID数组
const targetCategories = [
  "62bacb137e6e0b6ac850b9ce",
  "63a7b5bb333394043fdca923"
];

const products = await Product.aggregate([
  {
    $match: {
      $text: { $search: `\"${searchText}\"` },
      // 核心:用$all匹配同时包含所有目标分类ID的文档
      category: { $all: targetCategories }
    }
  },
  {
    $project: {
      name: 1,
      category: 1,
      avgRating: { $floor: { $avg: "$ratings.star" } },
      price: 1,
      slug: 1,
      images: 1,
      color: 1,
      description: 1,
      ratings: 1,
      sold: 1
    }
  }
]);

方法二:后续阶段过滤(仅特殊场景使用)

如果因业务限制无法在$match阶段提前过滤,可以在聚合中间阶段通过集合交集判断文档是否符合条件:

const targetCategories = [
  "62bacb137e6e0b6ac850b9ce",
  "63a7b5bb333394043fdca923"
];

const products = await Product.aggregate([
  {
    $match: {
      $text: { $search: `\"${searchText}\"` }
    }
  },
  {
    $addFields: {
      // 计算当前文档category与目标数组的交集长度,判断是否等于目标数组长度
      hasAllCategories: {
        $eq: [
          { $size: { $setIntersection: ["$category", targetCategories] } },
          targetCategories.length
        ]
      }
    }
  },
  // 仅保留符合条件的文档
  { $match: { hasAllCategories: true } },
  {
    $project: {
      name: 1,
      category: 1,
      avgRating: { $floor: { $avg: "$ratings.star" } },
      price: 1,
      slug: 1,
      images: 1,
      color: 1,
      description: 1,
      ratings: 1,
      sold: 1,
      hasAllCategories: 0 // 移除临时字段
    }
  }
]);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 00:37:02