首页 > 解决方案 > MongoDB:如何使用条件递归获取所有子节点的计数?

问题描述

如何使用条件递归获取所有子节点的计数?

我有这样一个集合的结构:

| id | parentID    | type   |
-----------------------------
| 1  | NULL        | A      |
-----------------------------
| 2  | 1           | B      |
-----------------------------
| 3  | 1           | B      |
-----------------------------
| 4  | 2           | C      |
-----------------------------
| 5  | 2           | C      |
-----------------------------
| 6  | 2           | B      |
-----------------------------

并想要这样的输出:

[
        {
            "id": 1,
            "parentId": null,
            "type": "A",
            "childBCount": 3
        },
        {
            "id": 2,
            "parentId": 1,
            "type": "B",
            "childBCount": 1
        },
        {
            "id": 3,
            "parentId": 1,
            "type": "B",
            "childBCount": 0
        },
        {
            "id": 4,
            "parentId": 2,
            "type": "C",
            "childBCount": 0
        },
        {
            "id": 5,
            "parentId": 2,
            "type": "C",
            "childBCount": 0
        },
        {
            "id": 6,
            "parentId": 2,
            "type": "C",
            "childBCount": 0
        }
    ]

我曾尝试使用graphlookup,但它没有为我提供向 graphlookup 阶段添加条件的选项。

我使用如下查询

modelName.aggregate([
    {
        $graphLookup: {
            from: "modelName",
            startWith: "$id",
            connectFromField: "id",
            connectToField: "parentId",
            as: "children",
        },
    }
])
.allowDiskUse(true);

但是想要这样的东西,我可以在graphlookup阶段添加条件

modelName.aggregate([
    {
        $graphLookup: {
            from: "modelName",
            startWith: "$id",
            connectFromField: "id",
            connectToField: "parentId",
            as: "children",
            match:[
                {
                    type:"B"
                }
            ]
        },
    }
])
.allowDiskUse(true);

标签: node.jsdatabasemongodbgraphlookup

解决方案


$graphLookup 具有以下原型形式:

{
   $graphLookup: {
      from: <collection>,
      startWith: <expression>,
      connectFromField: <string>,
      connectToField: <string>,
      as: <string>,
      maxDepth: <number>,
      depthField: <string>,
      restrictSearchWithMatch: <document>
   }
}

这里<document>遵循通常的查询过滤器语法,但需要注意的是您不能使用聚合表达式。

因此,您可以将条件添加到restrictSearchWithMatch属性中,如下所示:

modelName.aggregate([
    {
        $graphLookup: {
            from: "modelName",
            startWith: "$id",
            connectFromField: "id",
            connectToField: "parentId",
            as: "children",
            restrictSearchWithMatch: { "type": "B" }
        },
    }
])
.allowDiskUse(true);

推荐阅读