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

MongoDB聚合:不使用Mongoose关联嵌套数组的subject与content文档

MongoDB 嵌套数组关联聚合解决方案(不使用Mongoose)

完全可以直接通过MongoDB原生聚合框架实现该需求,无需依赖Mongoose。以下是针对你的场景设计的聚合管道:

聚合管道代码

db.subject.aggregate([
  // 拆解topics数组,将每个topic转为独立文档
  { $unwind: "$topics" },
  // 拆解每个topic下的content数组,将每个content项转为独立文档
  { $unwind: "$topics.content" },
  // 关联content集合,仅匹配包含contentId的content项
  {
    $lookup: {
      from: "content",
      localField: "topics.content.contentId",
      foreignField: "_id",
      as: "contentDetails"
    }
  },
  // 合并关联结果与原content项的字段
  {
    $addFields: {
      "topics.content": {
        $cond: {
          // 判断当前content项是否有contentId
          if: { $ne: ["$topics.content.contentId", undefined] },
          // 有则合并content文档数据与visibility字段
          then: {
            $mergeObjects: [
              { $arrayElemAt: ["$contentDetails", 0] },
              { visibility: "$topics.content.visibility" }
            ]
          },
          // 没有则保留原content项
          else: "$topics.content"
        }
      }
    }
  },
  // 移除临时的contentDetails字段
  { $unset: "contentDetails" },
  // 按topic的id分组,重新组装content数组
  {
    $group: {
      _id: {
        subjectId: "$_id",
        topicId: "$topics.id",
        topicName: "$topics.name",
        topicDescription: "$topics.description",
        subjectName: "$name",
        subjectDescription: "$description",
        subjectLanguage: "$language"
      },
      content: { $push: "$topics.content" }
    }
  },
  // 重组topic结构
  {
    $addFields: {
      "topics.id": "$_id.topicId",
      "topics.name": "$_id.topicName",
      "topics.description": "$_id.topicDescription",
      "topics.content": "$content"
    }
  },
  // 移除临时分组字段
  { $unset: ["_id", "content"] },
  // 按subject的id分组,重新组装topics数组
  {
    $group: {
      _id: "$_id.subjectId",
      name: { $first: "$_id.subjectName" },
      description: { $first: "$_id.subjectDescription" },
      language: { $first: "$_id.subjectLanguage" },
      topics: { $push: "$topics" }
    }
  }
])

逻辑说明

  1. 多层拆解数组:通过两次$unwind将嵌套的topics和topics.content数组拆解为扁平结构,方便后续关联操作。
  2. 精准关联:$lookup仅对包含contentId的content项关联content集合,避免无效匹配。
  3. 字段合并:使用$mergeObjects将关联到的content文档数据与原项的visibility字段合并,保留你需要的所有信息。
  4. 重新组装结构:通过两次$group逐步将扁平数据重新聚合为原始的嵌套数组结构,还原subject文档的层级。

执行该聚合管道后,即可得到你期望的结果。

内容的提问来源于stack exchange,提问作者Marek Balvín

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 06:25:06