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

MongoDB聚合$unwind后$group保留父结构并重组嵌套数组方案

MongoDB聚合嵌套数组筛选后结构重组方案

最优实现方案(避免冗余unwind)

直接通过数组操作符完成嵌套筛选,无需展开数组,天然保留原父级结构,性能更优:

const targetSigningPerson = ObjectId("你的指定签署人ID");
db.songs.aggregate([
  // 1. 关联agreements集合
  {
    $lookup: {
      from: "agreements",
      localField: "关联字段",
      foreignField: "关联字段",
      as: "agreements"
    }
  },
  // 2. 嵌套筛选符合条件的协议版本
  {
    $addFields: {
      agreements: {
        $filter: {
          input: {
            $map: {
              input: "$agreements",
              as: "agreement",
              in: {
                // 保留协议所有父级字段
                $mergeObjects: [
                  "$$agreement",
                  {
                    agreementVersion: {
                      $filter: {
                        input: "$$agreement.agreementVersion",
                        as: "version",
                        cond: { $eq: ["$$version.isLatestVersion", true] }
                      }
                    }
                  }
                ]
              }
            }
          },
          as: "filteredAgreement",
          cond: { $gt: [{ $size: "$$filteredAgreement.agreementVersion" }, 0] }
        }
      }
    }
  },
  // 3. 筛选版本下符合条件的approvalStatus
  {
    $addFields: {
      agreements: {
        $map: {
          input: "$agreements",
          as: "agreement",
          in: {
            $mergeObjects: [
              "$$agreement",
              {
                agreementVersion: {
                  $map: {
                    input: "$$agreement.agreementVersion",
                    as: "version",
                    in: {
                      // 保留版本所有父级字段
                      $mergeObjects: [
                        "$$version",
                        {
                          approvalStatus: {
                            $filter: {
                              input: "$$version.approvalStatus",
                              as: "status",
                              cond: {
                                $and: [
                                  { $eq: ["$$status.signingPerson", targetSigningPerson] },
                                  { $ne: ["$$status.isApprovedByUser", true] }
                                ]
                              }
                            }
                          }
                        }
                      ]
                    }
                  }
                }
              }
            ]
          }
        }
      }
    }
  },
  // 可选:过滤掉没有匹配审批状态的空版本/空协议
  {
    $addFields: {
      agreements: {
        $filter: {
          input: "$agreements",
          as: "agreement",
          cond: {
            $gt: [
              {
                $size: {
                  $filter: {
                    input: "$$agreement.agreementVersion",
                    as: "v",
                    cond: { $gt: [{ $size: "$$v.approvalStatus" }, 0] }
                  }
                }
              },
              0
            ]
          }
        }
      }
    }
  }
])

兼容unwind+group写法

如果必须保留先展开再匹配的原有逻辑,调整$group阶段的分组规则即可:

// $unwind、$match阶段和原有逻辑一致,仅修改$group阶段
{
  $group: {
    // 按歌曲ID+协议ID+版本ID作为唯一分组键,保证同协议同版本只留一份
    _id: {
      songId: "$_id",
      agreementId: "$agreements._id",
      versionId: "$agreements.agreementVersion._id"
    },
    // 保留歌曲根字段
    songField: { $first: "$需要保留的歌曲字段" },
    // 保留协议父级字段
    agreementField: { $first: "$agreements.需要保留的协议字段" },
    // 保留版本父级字段
    versionField: { $first: "$agreements.agreementVersion.需要保留的版本字段" },
    // 合并匹配到的所有审批状态
    matchedApprovalStatus: { $push: "$agreements.agreementVersion.approvalStatus" }
  }
}

核心注意点

  • 嵌套数组筛选优先用$map+$filter+$mergeObjects组合,避免多层unwind带来的结构碎片化问题
  • 分组时唯一键必须同时包含协议ID和版本ID,才能保证同协议的不同版本不会被错误合并
  • $ne: ["$$status.isApprovedByUser", true] 可以同时覆盖字段不存在和值为false两种场景,无需额外写$exists判断

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 23:42:03