我有mongodb $graphLookup
聚合的输出:
db.getCollection('projects').aggregate([
{
$lookup: {
from: "projects",
localField: "_id",
foreignField: "parent",
as: "childrens"
}
}
])
{
"_id" : "1",
"name" : "Project1",
"parent" : null,
"childrens" : [
{
"_id" : "3",
"name" : "ProjectForId1",
"parent" : "1"
}
]
},
{
"_id" : "3",
"name" : "ProjectForId1",
"parent" : "1",
"childrens" : [
{
"_id" : "6",
"name" : "ProjectForId3",
"parent" : "3"
},
{
"_id" : "7",
"name" : "ProjectForId3",
"parent" : "3"
}
]
}
我需要从javascript中的此输出构建层次结构,或者如果可能直接从查询中构建层次结构,则最终输出应类似于:
{
"_id" : "1",
"name" : "Project1",
"parent" : null,
"childrens" : [
{
"_id" : "3",
"name" : "ProjectForId1",
"parent" : "1",
"childrens" : [
{
"_id" : "6",
"name" : "ProjectForId3",
"parent" : "3"
},
{
"_id" : "7",
"name" : "ProjectForId3",
"parent" : "3"
}
]
}
]
}
如果有人在其他情况下有勇敢的心可以提供帮助,则可以通过过滤_id来创建层次结构:
ex:对于_id = "1"
,输出将与上面相同,但是如果_id
为3
,则最终输出应类似于:
{
"_id" : "3",
"name" : "ProjectForId1",
"parent" : "1",
"childrens" : [
{
"_id" : "6",
"name" : "ProjectForId3",
"parent" : "3"
},
{
"_id" : "7",
"name" : "ProjectForId3",
"parent" : "3"
}
]
}
答案 0 :(得分:1)
以下解决方案与我过去的答案大致相同,因此您可以得到详尽的解释here
db.projects.aggregate([
{
$graphLookup: {
from: "projects",
startWith: "$_id",
connectFromField: "_id",
connectToField: "parent",
as: "children",
maxDepth: 4,
depthField: "level"
}
},
{
$unwind: "$children"
},
{
$sort: { "children.level": -1 }
},
{
$group: {
_id: "$_id",
children: { $push: "$children" }
}
},
{
$addFields: {
children: {
$reduce: {
input: "$children",
initialValue: {
currentLevel: -1,
currentLevelProjects: [],
previousLevelProjects: []
},
in: {
$let: {
vars: {
prev: {
$cond: [
{ $eq: [ "$$value.currentLevel", "$$this.level" ] },
"$$value.previousLevelProjects",
"$$value.currentLevelProjects"
]
},
current: {
$cond: [
{ $eq: [ "$$value.currentLevel", "$$this.level" ] },
"$$value.currentLevelProjects",
[]
]
}
},
in: {
currentLevel: "$$this.level",
previousLevelProjects: "$$prev",
currentLevelProjects: {
$concatArrays: [
"$$current",
[
{ $mergeObjects: [
"$$this",
{ children: { $filter: { input: "$$prev", as: "e", cond: { $eq: [ "$$e.parent", "$$this._id" ] } } } }
] }
]
]
}
}
}
}
}
}
}
},
{
$addFields: { children: "$children.currentLevelProjects" }
},
{
$match: {
_id: "1"
}
}
])
上一个阶段应该是过滤,因此您可以在此处获取任何深度级别的数据。