Es ist non-trivial
Lösung.
ANFORDERUNGEN
1 Wir müssen ein zusätzliches Feld hinzufügen (nennen wir es level
), die angibt, wo sich das Dokument innerhalb der Hierarchie befindet.
|root 0
|-child A 1
|--child A_1 2
|-child B 1
2 Wir müssen define
vorher Hierarchietiefe (zB:max 3)
EINSCHRÄNKUNG
Um von einer bestimmten Ebene zu filtern, müssen wir root
ändern und children
$match Werte.
Achten Sie immer auf die Hierarchieebene:
root - 0
children - 1
root - 1
children - 2
LÖSUNG
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 (maximale Tiefe:3) | MongoPlayground (maximale Tiefe:4)
ERKLÄRUNG
-
Mit
$facet
Wir definieren die Ebenenstruktur.root
nur alle Root-Verzeichnisse.children
enthält alle Kinder mit Level 1 + Kindernachkommen. -
Wir
$filter
(Merge) Stamm und Kinder durchparentId
-
Mit
$project
und$replaceRoot
wir geben die ursprüngliche Struktur zurück.
LINKS
https://docs.mongodb.com/manual/reference/operator/ Aggregation/Facette/
https://docs.mongodb.com/manual/ Referenz/Operator/Aggregation/Filter/
https://docs.mongodb.com/manual/ Referenz/Operator/Aggregation/ReplaceRoot/