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

MongoDB聚合分组与对象数组映射技术求助

解决MongoDB分组聚合并关联集合的需求

嘿,我来帮你搞定这个聚合需求!首先先纠正你现有代码里的小语法错误,再一步步完成关联和格式转换——另外注意你写的期望结果里的对象语法有点小问题,应该是规范的键值对结构,比如{name: "cooking", value: 3},下面的实现会按这个合理结构来输出。

首先,你当前的$group阶段语法有误,正确写法应该是:

db.talent.aggregate([
  { $group: { _id: '$id', skills: { $addToSet: '$skill' } } }
])

执行后会得到:[{_id: "1", skills: ["cooking", "fishing"]}](分组后的主键默认是_id,后面我们会把它改成你要的id字段)

接下来要关联你的技能值集合(假设这个集合名叫skillValues,记得替换成你的实际集合名),并把技能列表转换成带value的对象格式,完整的聚合管道如下:

db.talent.aggregate([
  // 1. 按id分组,收集对应技能列表
  {
    $group: {
      _id: '$id',
      skills: { $addToSet: '$skill' } // 用$addToSet去重,允许重复就换$push
    }
  },
  // 2. 关联技能值集合,匹配每个技能对应的value
  {
    $lookup: {
      from: 'skillValues', // 替换为你的关联集合名称
      localField: 'skills',
      foreignField: 'name',
      as: 'skillDetails'
    }
  },
  // 3. 重组输出格式,得到期望的结构
  {
    $project: {
      id: '$_id', // 把默认的_id重命名为你要的id
      _id: 0, // 隐藏默认的_id字段
      skills: {
        $map: {
          input: '$skillDetails',
          as: 'detail',
          in: {
            name: '$$detail.name',
            value: '$$detail.value'
          }
        }
      }
    }
  }
])

各阶段说明:

  • $group阶段:按id对talent集合分组,用$addToSet收集每个id对应的不重复技能列表;如果你的场景允许同一个id有重复技能,把$addToSet换成$push即可。
  • $lookup阶段:将分组得到的skills数组与关联集合的name字段匹配,把匹配到的技能详情(包含name和value)存入skillDetails数组。
  • $project阶段:重新整理输出结构,将_id重命名为id并隐藏原_id,再用$map遍历skillDetails,把每个详情转换成{name: "...", value: ...}的格式。

执行这个聚合管道后,就能得到符合预期的结果:

[{
  "id": "1",
  "skills": [
    {"name": "cooking", "value": 3},
    {"name": "fishing", "value": 2}
  ]
}]

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 06:42:16