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

MongoDB聚合Facet子管道结果按员工名称关联合并的实现问询

MongoDB Facet结果关联合并方案

问题场景

集合文档结构:

type: 可选值为a1或a2
emp_name: 字符串类型
status: 可选值为0或1

当前使用$facet定义了两个子管道:

  • a1子管道:过滤type=a1的数据,按emp_name分组统计数量,最终输出empName和count字段
  • a2子管道:过滤type=a2的数据,输出type、emp_name、status字段

现在需要将两个子管道的结果按empName(a1)和emp_name(a2)匹配,合并为包含empName、count、type、status的单个对象。

解决方案

可以通过在$facet之后添加额外聚合阶段实现关联合并,完整管道如下:

[
  {
    $facet: {
      a1: [
        { $match: { type: "a1" } },
        { $group: { _id: "$emp_name", count: { $sum: 1 } } },
        { $project: { empName: "$_id", count: 1, _id: 0 } }
      ],
      a2: [
        { $match: { type: "a2" } },
        { $project: { emp_name: 1, status: 1, type: 1, _id: 0 } }
      ]
    }
  },
  { $unwind: "$a1" },
  {
    $lookup: {
      from: { $literal: "$$CURRENT.a2" },
      localField: "a1.empName",
      foreignField: "emp_name",
      as: "matchedA2"
    }
  },
  { $unwind: { path: "$matchedA2", preserveNullAndEmptyArrays: true } },
  {
    $replaceRoot: {
      newRoot: {
        $mergeObjects: [
          "$a1",
          {
            type: "$matchedA2.type",
            status: "$matchedA2.status",
            empName: { $ifNull: ["$a1.empName", "$matchedA2.emp_name"] }
          }
        ]
      }
    }
  }
]

关键步骤说明

  1. 优化a1子管道:将$group的_id直接设为$emp_name,简化后续投影逻辑
  2. $unwind展开a1数组:将a1的每个统计对象单独拆分,便于逐个关联
  3. $lookup关联a2数据:利用$literal引用当前文档的a2数组作为关联数据源,通过empName和emp_name匹配
  4. 保留无匹配记录:preserveNullAndEmptyArrays: true确保即使a1的员工在a2中无对应数据,也不会丢失统计记录
  5. 合并字段到根对象:通过$mergeObjects整合a1和匹配到的a2字段,用$ifNull保证empName字段统一存在

如果需要保留a2中无对应a1统计的记录,可以调整管道顺序,先展开a2再关联a1,或者添加额外逻辑处理双向合并。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 20:15:27