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

MongoDB聚合$project中用$sum+$eq统计attendance状态结果为0的问题

错误原因

  • $lookup 关联查询返回的 attendance 字段是数组类型,直接取 $attendance.status 得到的是所有子文档status字段组成的数组(示例中对应值为 ["present"]),数组和字符串 "present" 做相等判断永远返回 false,布尔值在 $sum 计算时会被转换为0,因此统计结果恒为0。
  • 你当前的写法中 $sum 直接作用于单条布尔表达式,不会遍历 attendance 数组的子元素,无法统计数组内符合条件的记录数量。

修复方案

你可以通过$map遍历数组匹配状态后累加,或者用$filter过滤符合条件的元素后取数组长度实现统计,以下是修改后的完整聚合代码:

Employee.aggregate([
  {
    $lookup: {
      from: "Attendance",
      let: { employeeId: "$_id" },
      pipeline: [
        {
          $match: {
            $and: [
              { $expr: { $eq: ["$employeeId", "$$employeeId"] } },
              { isApproved: true },
              {
                createdAt: {
                  $gte: startOfMonth.toDate(),
                  $lte: endOfMonth.toDate(),
                },
              },
            ],
          },
        },
      ],
      as: "attendance",
    },
  },
  {
    $project: {
      _id: 1,
      username: 1,
      name: 1,
      attendance: 1,
      present: {
        $sum: {
          $map: {
            input: "$attendance",
            in: { $cond: [{ $eq: ["$$this.status", "present"] }, 1, 0] }
          }
        }
      },
      sick: {
        $sum: {
          $map: {
            input: "$attendance",
            in: { $cond: [{ $eq: ["$$this.status", "sick"] }, 1, 0] }
          }
        }
      },
      off: {
        $sum: {
          $map: {
            input: "$attendance",
            in: { $cond: [{ $eq: ["$$this.status", "off"] }, 1, 0] }
          }
        }
      }
    },
  },
]);

也可以用$filter简化写法,效果完全一致:

present: {
  $size: {
    $filter: {
      input: "$attendance",
      cond: { $eq: ["$$this.status", "present"] }
    }
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 21:54:03