@ kmandalas Я сталкиваюсь с такой проблемой за последние 2 дня, моя коллекция немного отличается, но концепция такая же, как ваша. Надеюсь, то, что я написал, поможет вам получить результат (я использую ссылку наSO ответы)
Моя схема сбора выглядит так:
const Category = new Schema({
sTitle: { type: String, trim: true },
iParentId: { type: mongoose.Schema.Types.ObjectId, ref: 'Category' },
bStatus: { type: Boolean, default: true },
dUpdatedAt: { type: Date },
dCreatedAt: { type: Date, default: Date.now }
});
Во-первых, я использую $ graphLookup, затем я собрал всех детей в одного подходящего родителя, например:
{
"_id": "5c6fa228c30bbf02cf12fe6c",
"sTitle": "firstParent",
"childrens":[{obj},{obj},{obj},{obj}] // Childrens as well as grandChild
},
{
"_id": "5c80d644ab57dd06d48cc474",
"sTitle": "secondParent",
"childrens":[] //No Child
},
.....
Получив такой результат, я создаю дерево в узле js без использования сторонней библиотеки lib.древовидный логический код :(! note: docs - это вывод $ graphlooup больше ничего)
function list_to_tree(list) {
var map = {}, node, roots = [], i;
for (i = 0; i < list.length; i += 1) {
map[list[i]._id] = i;
list[i].children = [];
}
for (i = 0; i < list.length; i += 1) {
node = list[i];
if (node.iParentId !== null && map[node.iParentId] !== undefined) {
var node2 = { //Because i need only _id,Title & childrens
_id: node._id,
Title: node.sTitle,
children: node.children
}
list[map[node.iParentId]].children.push(node2); //You can push direct "node"
} else {
var node2 = {
_id: node._id,
Title: node.sTitle,
children: node.children
}
roots.push(node2);
}
}
return roots;
}
let final_result = [] //For Storing all parent with childs
if (docs.length >= 0) {
docs.map(single_doc => { //For getting all parent Tree
var single_child = list_to_tree(single_doc.children)
var obj = {
_id: single_doc._id,
Title: single_doc.sTitle,
children: single_child
}
final_result.push(obj)
})
}
console.log("Final Tree is : ",final_result)
Надеюсь, это поможет Вам