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

MongoDB聚合使用$match时如何返回含空cards数组的lists?

问题原因

你当前查询返回空的核心原因是$unwind操作对空数组的处理逻辑和你后续$match的匹配规则冲突:

  • 你对$boards.lists.cards执行$unwind并开启preserveNullAndEmptyArrays后,原cards: []的条目会被转为boards.lists.cards = null,不再是数组类型,因此$size: 0的条件永远无法命中,导致全部数据被过滤。
  • 另外你的匹配逻辑不需要拆分cards数组就能实现,拆分后反而增加了后续分组的复杂度。

修复后的聚合代码

docs = await WorkspaceModel.aggregate([
  { $match: { _id: mongoose.Types.ObjectId(workspaceId) } },
  { $unwind: "$boards" },
  { $match: { "boards._id": mongoose.Types.ObjectId(boardId) } },
  { $unwind: "$boards.lists" },
  // 先过滤掉已归档的list
  { $match: { "boards.lists.archived": false } },
  // 直接判断当前list是否满足条件:cards为空 或 存在至少一个未归档卡片
  {
    $match: {
      $or: [
        { "boards.lists.cards": { $size: 0 } },
        { "boards.lists.cards.archived": false }
      ]
    }
  },
  // 分组重组数据
  {
    $group: {
      _id: "$boards._id",
      name: { $first: "$boards.name" },
      color: { $first: "$boards.color" },
      labels: { $first: "$boards.labels" },
      lists: { $push: "$boards.lists" },
    },
  },
]).exec();

注:这里把$addToSet换成了$push,避免list顺序错乱,如果你不需要保序可以保留原来的$addToSet。

关键修改点

  • 删除了不必要的$unwind拆分cards的步骤,直接对list下的cards数组做条件判断,MongoDB支持直接对数组字段的嵌套属性做匹配,只要数组里有任意一个元素满足archived: false就会命中条件。
  • 修正了空cards数组的匹配规则,未拆分数组时$size: 0可以正确命中空数组的list。
  • 简化了查询逻辑,执行效率也会更高。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 13:54:04