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

MongoDB聚合查询多级嵌套数组过滤及结构保留问题求助

多级嵌套数组过滤解决方案(保留原结构/恢复结构)

针对你的MongoDB多级嵌套数组过滤需求,以下两种方案分别实现保留原结构过滤和**$unwind后恢复结构**:


方案1:用$map+$filter逐层过滤(无需$unwind,保留原结构)

你的二级list是数组套数组的结构,直接用$filter会因层级路径问题失效,需逐层遍历+筛选:

db.runoob.aggregate([
  // 匹配顶层文档,缩小处理范围
  {
    $match: {
      $or: [
        { name: 1, "list.name": 11 },
        { name: 6, "list.name": 12 }
      ]
    }
  },
  // 逐层过滤嵌套数组
  {
    $project: {
      id: 1,
      name: 1,
      list: {
        $filter: {
          input: "$list",
          as: "topItem",
          // 筛选顶层list中符合条件的元素
          cond: {
            $or: [
              { $and: [{ $in: ["$$topItem.id", [11, 12]] }, { $eq: ["$$topItem.name", 11] }] },
              { $and: [{ $in: ["$$topItem.id", [61, 62]] }, { $eq: ["$$topItem.name", 12] }] }
            ]
          },
          // 构造筛选后的顶层list元素,同时处理内层嵌套数组
          in: {
            id: "$$topItem.id",
            name: "$$topItem.name",
            list: {
              // 先遍历内层的数组套数组,过滤每个子数组中name=111的元素
              $map: {
                input: "$$topItem.list",
                as: "subArray",
                in: {
                  $filter: {
                    input: "$$subArray",
                    as: "innerItem",
                    cond: { $eq: ["$$innerItem.name", 111] }
                  }
                }
              },
              // 可选:移除内层list中为空的子数组
              $filter: {
                input: {
                  $map: {
                    input: "$$topItem.list",
                    as: "subArray",
                    in: {
                      $filter: {
                        input: "$$subArray",
                        as: "innerItem",
                        cond: { $eq: ["$$innerItem.name", 111] }
                      }
                    }
                  }
                },
                as: "filteredSubArr",
                cond: { $gt: [{ $size: "$$filteredSubArr" }, 0] }
              }
            }
          }
        }
      }
    }
  }
])

核心说明:

  • 内层list是数组套数组结构,需先用$map遍历每个子数组,再用$filter筛选子数组内的目标元素
  • 最后可选加一层$filter,移除内层list中为空的子数组(按需启用)

方案2:$unwind后恢复原结构

如果已用$unwind打散数组,可通过$group逐层聚合恢复嵌套结构:

db.runoob.aggregate([
  // 打散所有嵌套数组
  { $unwind: "$list" },
  { $unwind: "$list.list" },
  { $unwind: "$list.list" },
  // 匹配目标数据
  {
    $match: {
      $or: [
        { name: 1, "list.name": 11, "list.list.name": 111 },
        { name: 6, "list.name": 12, "list.list.name": 111 }
      ]
    }
  },
  // 第一步:聚合最内层数组
  {
    $group: {
      _id: {
        docId: "$_id",
        topId: "$list.id",
        topName: "$list.name",
        docName: "$name"
      },
      innerList: { $push: "$list.list" }
    }
  },
  // 第二步:聚合顶层list数组
  {
    $group: {
      _id: {
        docId: "$_id.docId",
        docName: "$_id.docName"
      },
      list: {
        $push: {
          id: "$_id.topId",
          name: "$_id.topName",
          list: ["$innerList"] // 恢复数组套数组的原始结构
        }
      }
    }
  },
  // 第三步:恢复顶层文档字段
  {
    $project: {
      _id: "$_id.docId",
      name: "$_id.docName",
      list: 1
    }
  }
])

核心说明:

  • $group的_id需包含上一层级的唯一标识,确保聚合后结构与原始数据一致
  • 最后通过$project恢复顶层文档的原始字段名(如id、name)

内容的提问来源于stack exchange,提问作者周维明

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 14:17:51