レベルがあると信じています フィールド$reduceを使用して、配列から階層構造を構築できます。これを実現するには、reportees
を取得する必要があります $graphLookup
の後にレベルの降順で並べ替えられます 。残念ながら、現在それを行う唯一の方法は、$ unwind + $ sort + $ groupを使用することです。これにより、集計が非常に長くなります。
次に、$reduce
を使用してその順序付けられた配列を処理できます 。各ステップで、従業員をreportees
を含む結果セットに追加する必要があります。 前のレベルから。さらに、level
を検出する必要があります 処理中に変更し、その場合はヘルパー配列を再配置します。
$ addFieldsは、既存のreportees
を置き換えるだけです。 この場合のフィールド。 $ concatArraysを使用すると、現在の従業員を追加できます($$this
)結果に。 $ filterを使用すると、reportees
を取得できます。 下位レベルから。
db.getCollection('employees').aggregate([
{
$match: {
empId : "10"
}
},
{
$graphLookup: {
from: "employees",
startWith: "$empId",
connectFromField: "empId",
connectToField: "managerId",
as: "reportees",
maxDepth: 4,
depthField: "level"
}
},
{
$project: {
"empId":1,
"managerId":1,
"reportees.empId":1,
"reportees.name":1,
"reportees.managerId":1,
"reportees.level":1
}
},
{
$unwind: "$reportees"
},
{
$sort: { "reportees.level": -1 }
},
{
$group: {
_id: "$_id",
empId: { $first: "$empId" },
managerId: { $first: "$managerId" },
reportees: { $push: "$reportees" }
}
},
{
$addFields: {
reportees: {
$reduce: {
input: "$reportees",
initialValue: {
currentLevel: -1,
currentLevelEmployees: [],
previousLevelEmployees: []
},
in: {
$let: {
vars: {
prev: {
$cond: [
{ $eq: [ "$$value.currentLevel", "$$this.level" ] },
"$$value.previousLevelEmployees",
"$$value.currentLevelEmployees"
]
},
current: {
$cond: [
{ $eq: [ "$$value.currentLevel", "$$this.level" ] },
"$$value.currentLevelEmployees",
[]
]
}
},
in: {
currentLevel: "$$this.level",
previousLevelEmployees: "$$prev",
currentLevelEmployees: {
$concatArrays: [
"$$current",
[
{ $mergeObjects: [
"$$this",
{ reportees: { $filter: { input: "$$prev", as: "e", cond: { $eq: [ "$$e.managerId", "$$this.empId" ] } } } }
] }
]
]
}
}
}
}
}
}
}
},
{
$addFields: { reportees: "$reportees.currentLevelEmployees" }
}
]).pretty()
上記のソリューションは、複数のレベルで機能するはずです。出力:
{
"_id" : "10",
"empId" : "10",
"managerId" : "15",
"reportees" : [
{
"empId" : "6",
"name" : "Employee6",
"managerId" : "10",
"level" : NumberLong(0),
"reportees" : [
{
"empId" : "1",
"name" : "Employee1",
"managerId" : "6",
"level" : NumberLong(1),
"reportees" : [ ]
},
{
"empId" : "2",
"name" : "Employee2",
"managerId" : "6",
"level" : NumberLong(1),
"reportees" : [ ]
}
]
},
{
"empId" : "8",
"name" : "Employee8",
"managerId" : "10",
"level" : NumberLong(0),
"reportees" : [
{
"empId" : "5",
"name" : "Employee5",
"managerId" : "8",
"level" : NumberLong(1),
"reportees" : [ ]
},
{
"empId" : "4",
"name" : "Employee4",
"managerId" : "8",
"level" : NumberLong(1),
"reportees" : [ ]
}
]
}
]
}