MongoDB: как получить количество всех дочерних узлов рекурсивно с условием?

#node.js #database #mongodb #graphlookup

#node.js #База данных #mongodb #graphlookup

Вопрос:

Как получить количество всех дочерних узлов рекурсивно с условием?

У меня есть структура коллекции, подобная этой:

 | 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);
  

Комментарии:

1. Соответствует ли структура в вашем примере выводам в вашем примере?

Ответ №1:

$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);