Ini adalah non-trivial
solusi.
PERSYARATAN
1 Kita perlu menambahkan field tambahan (sebut saja level
) yang menunjukkan lokasi dokumen di dalam hierarki.
|root 0
|-child A 1
|--child A_1 2
|-child B 1
2 Kita perlu define
kedalaman hierarki sebelumnya (misalnya:maks 3)
BATASAN
Untuk memfilter dari level tertentu, kita perlu memodifikasi root
dan children
$match nilai.
Pastikan selalu tingkat hierarki:
root - 0
children - 1
root - 1
children - 2
SOLUSI
db.documents.aggregate([
{
$facet: {
root: [
{
$match: {
level: 0
}
}
],
children: [
{
$match: {
level: 1
}
},
{
$graphLookup: {
from: "documents",
startWith: "$_id",
connectFromField: "_id",
connectToField: "parentId",
maxDepth: 0,
as: "hierarchy"
}
},
{
$sort: {
_id: 1
}
}
]
}
},
{
$unwind: "$root"
},
{
$project: {
"root._id": 1,
"root.name": 1,
"root.level": 1,
"root.hierarchy": {
$filter: {
input: "$children",
as: "sub_level",
cond: {
$eq: [
"$$sub_level.parentId",
"$root._id"
]
}
}
}
}
},
{
$replaceRoot: {
newRoot: "$root"
}
}
])
MongoPlayground (kedalaman maks:3) | MongoPlayground (kedalaman maksimum:4)
Penjelasan
-
Dengan
$facet
kita mendefinisikan struktur tingkat.root
semua direktori root saja.children
berisi semua anak dengan level 1 + turunan anak. -
Kami
$filter
(gabungkan) root dan anak denganparentId
-
Dengan
$project
dan$replaceRoot
kami mengembalikan struktur aslinya.
LINK
https://docs.mongodb.com/manual/reference/operator/ agregasi/segi/
https://docs.mongodb.com/manual/ referensi/operator/agregasi/filter/
https://docs.mongodb.com/manual/ referensi/operator/agregasi/replaceRoot/