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

Mongoose关联student与exams集合并获取指定字段问题求助

解决Mongoose中关联数组内嵌套ID与集合的问题

我明白你遇到的困扰了——直接用$lookup关联top10.studentId时,没办法把每个学生的分数和他们的个人信息对应绑定,导致返回的结果和预期不符。这是因为top10是一个数组,直接关联会把所有匹配的学生一次性返回,丢失了和原数组中score的对应关系。

下面是可行的聚合查询方案,完美匹配你想要的输出结构:

return await Exams.aggregate([
  // 第一步:拆分top10数组,把每个元素转为单独的文档
  { $unwind: "$top10" },
  // 第二步:关联students集合,根据top10里的studentId匹配学生_id
  {
    $lookup: {
      from: "students",
      localField: "top10.studentId",
      foreignField: "_id",
      as: "studentInfo"
    }
  },
  // 第三步:拆分lookup返回的studentInfo数组(每个studentId对应一个学生,所以拆成单个对象)
  { $unwind: "$studentInfo" },
  // 第四步:重新按test字段分组,把拆分后的项整合回数组
  {
    $group: {
      _id: "$test",
      students: {
        $push: {
          studentId: "$top10.studentId",
          fullname: "$studentInfo.fullname",
          score: "$top10.score"
        }
      }
    }
  },
  // 第五步:调整输出格式,把_id改为test字段,移除默认的_id
  {
    $project: {
      _id: 0,
      test: "$_id",
      students: 1
    }
  }
]);

各步骤详解:

  • $unwind: "$top10":将exams文档中的top10数组拆分成多个独立文档,每个文档只包含top10中的一个元素,这样后续可以逐个关联学生信息。
  • $lookup:针对每个拆分后的top10.studentId,从students集合中匹配对应的学生文档,结果存入studentInfo数组。
  • $unwind: "$studentInfo":因为每个studentId只会匹配到一个学生,所以把studentInfo数组拆成单个对象,方便后续提取字段。
  • $group:以test字段为分组依据,将之前拆分的文档重新聚合,用$push把每个学生的studentId、fullname和对应的score整合到students数组中。
  • $project:调整最终输出的字段结构,把分组用的_id改为test,并移除默认的_id字段,完全匹配你期望的输出格式。

这样执行后,就能得到你想要的结果:

{
  "test": "Sample Test #1",
  "students": [
    {
      "studentId": "5f22ef443f17d8235332bbbe",
      "fullname": "John Smith",
      "score": 11
    },
    {
      "studentId": "5f281ad0838c6885856b6c01",
      "fullname": "Erlanie Jones",
      "score": 9
    },
    {
      "studentId": "5f64add93dc79c0d534a51d0",
      "fullname": "Krishna Kumar",
      "score": 5
    }
  ]
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 14:27:55