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

如何在MongoDB Compass中过滤递归嵌套的对象数组

MongoDB递归过滤嵌套children数组(保留status=ENABLED的项)

需求说明

  • 先筛选出满足menuVersion = "MENU_ORDER"且status = "ENABLED"的根文档
  • 递归过滤所有层级的children数组,仅保留其中status = "ENABLED"的子项(层级无上限)

示例集合

[
  {
    "_id": "MENU_ORDER_POS_1",
    "menuVersion": "MENU_ORDER",
    "menuType": "MAIN",
    "status": "ENABLED",
    "children": [
      {
        "_id": "MENU_ORDER_CHILD_1",
        "menuVersion": "MENU_ORDER",
        "status": "ENABLED",
        "children": [
          {
            "_id": "MENU_ORDER_CHILD_1.1",
            "menuVersion": "MENU_ORDER",
            "status": "ENABLED",
            "children": []
          },
          {
            "_id": "MENU_ORDER_CHILD_1.2",
            "menuVersion": "MENU_ORDER",
            "status": "DISABLED",
            "children": []
          }
        ]
      },
      {
        "_id": "MENU_ORDER_CHILD_2",
        "menuVersion": "MENU_ORDER",
        "status": "DISABLED",
        "children": []
      },
      {
        "_id": "MENU_ORDER_CHILD_3",
        "menuVersion": "MENU_ORDER",
        "status": "DISABLED",
        "children": []
      }
    ]
  },
  {
    "_id": "MENU_ORDER_POS_2",
    "menuVersion": "PANEL",
    "menuType": "",
    "defaultPath": "",
    "eventNameToNavigate": "",
    "status": "ENABLED",
    "children": []
  }
]

预期输出

{
  "_id": "MENU_ORDER_POS_1",
  "menuVersion": "MENU_ORDER",
  "menuType": "MAIN",
  "status": "ENABLED",
  "children": [
    {
      "_id": "MENU_ORDER_CHILD_1",
      "menuVersion": "MENU_ORDER",
      "status": "ENABLED",
      "children": [
        {
          "_id": "MENU_ORDER_CHILD_1.1",
          "menuVersion": "MENU_ORDER",
          "status": "ENABLED",
          "children": []
        }
      ]
    }
  ]
}

已尝试的代码(仅支持第一层过滤)

{
  children: {
    $filter: {
      input: "$children",
      as: "children",
      cond: {
        $eq: ["$$children.status", "ENABLED"]
      }
    }
  }
}

以上代码只能过滤第一层children,无法处理更深层级的嵌套数组。

完整聚合解决方案

利用MongoDB 4.4+支持的$function实现递归过滤,完整聚合管道如下:

[
  // 第一步:筛选符合条件的根文档
  {
    $match: {
      menuVersion: "MENU_ORDER",
      status: "ENABLED"
    }
  },
  // 第二步:递归过滤所有层级的children数组
  {
    $addFields: {
      children: {
        $function: {
          body: function filterEnabledChildren(items) {
            return items
              .filter(item => item.status === "ENABLED")
              .map(item => ({
                ...item,
                children: filterEnabledChildren(item.children || [])
              }));
          },
          args: ["$children"],
          lang: "js"
        }
      }
    }
  }
]

说明

  • $function允许在聚合中使用自定义JavaScript函数,这里通过递归函数filterEnabledChildren先过滤当前层的status=ENABLED项,再递归处理每个项的children数组
  • 确保你的MongoDB版本在4.4及以上,否则不支持$function
  • 若使用MongoDB 5.0+,也可以用$accumulator实现递归,但$function更直观易读

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.01 03:31:36