如何在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
相关产品推荐
相关产品推荐

