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

MongoDB聚合查询:关联双集合获取各办公地点对应的去重职位列表

错误原因

你原先的写法不符合$lookup的语法规范:标准$lookup不支持直接传入project/group配置,要实现关联阶段就处理员工数据、避免拉取全量员工文档的需求,需要使用MongoDB 3.6及以上版本支持的**带自定义pipeline的$lookup**语法。

最优实现方案

前置优化(必做,大幅提升查询效率)

给employees集合创建{office: 1, jobTitle: 1}联合索引,该索引可以直接覆盖关联查询、职位提取的全部需求,查询时不需要读取employees的完整文档,走索引即可返回所有需要的数据,性能提升非常明显。

正确聚合语句

db.offices.aggregate([
  {
    $lookup: {
      from: "employees",
      localField: "_id",
      foreignField: "office",
      // 关联阶段直接在employees侧完成聚合,仅返回去重后的职位列表,大幅减少数据传输量
      pipeline: [
        // 仅保留需要的jobTitle字段,过滤无关数据
        { $project: { jobTitle: 1, _id: 0 } },
        // 按jobTitle分组实现去重
        { $group: { _id: "$jobTitle" } },
        // 将去重后的职位合并为单个数组
        { $group: { _id: null, jobTitles: { $push: "$_id" } } },
        // 仅保留职位数组字段
        { $project: { jobTitles: 1, _id: 0 } }
      ],
      as: "tmpJobWrap"
    }
  },
  // 格式化输出结构,无员工的办公点返回空职位数组
  {
    $addFields: {
      jobTitles: { $ifNull: [ { $first: "$tmpJobWrap.jobTitles" }, [] ] }
    }
  },
  // 移除临时字段,返回符合要求的结构
  {
    $project: {
      tmpJobWrap: 0
    }
  }
])

低版本MongoDB兼容方案(3.6以下版本使用,性能略差)

如果你的MongoDB版本不支持带pipeline的$lookup,可以用以下写法实现:

db.offices.aggregate([
  {
    $lookup: {
      from: "employees",
      localField: "_id",
      foreignField: "office",
      as: "empList"
    }
  },
  // 拉取所有员工后做职位去重
  {
    $addFields: {
      jobTitles: {
        $reduce: {
          input: "$empList",
          initialValue: [],
          in: { $setUnion: [ "$$value", [ "$$this.jobTitle" ] ] }
        }
      }
    }
  },
  // 移除临时字段
  { $project: { empList: 0 } }
])

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 22:36:03