node.jsdatabasemongodbgraphlookup

MongoDB: how to get the count of all the child nodes recursively with the condition?


How to get the count of all the child nodes recursively with the condition?

I have the structure of a collection like this:

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

And wanted an Output like this:

[
        {
            "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
        }
    ]

I have tried using graphlookup but it did't provide me the option to add condition to graphlookup stage.

I have using the query like below

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

But wanted something like this where i can add condition to graphlookup stage

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

Solution

  • $graphLookup has the following prototype form:

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

    Here <document> follows the usual query filter syntax with the caveat that you cannot use aggregation expressions.

    Therefore, you can add your condition to restrictSearchWithMatch property as follows:

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