C'est non-trivial
solution.
CONFIGURATIONS
1 Nous devons ajouter un champ supplémentaire (appelons-le level
) qui indique où se trouve le document dans la hiérarchie.
|root 0
|-child A 1
|--child A_1 2
|-child B 1
2 Nous devons define
anciennement profondeur de la hiérarchie (par exemple :max 3)
LIMITATION
Afin de filtrer à partir d'un niveau spécifique, nous devons modifier root
et children
$match valeurs.
Assurez-vous toujours du niveau hiérarchique :
root - 0
children - 1
root - 1
children - 2
SOLUTION
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 (profondeur max :3) | MongoPlayground (profondeur max :4)
EXPLICATION
-
Avec
$facet
nous définissons la structure de niveau.root
tous les répertoires racine uniquement.children
contient tous les enfants de niveau 1 + enfants descendants. -
Nous
$filter
(fusionner) racine et enfants parparentId
-
Avec
$project
et$replaceRoot
nous retournons la structure d'origine.
LIENS
https://docs.mongodb.com/manual/reference/operator/ agrégation/facette/
https://docs.mongodb.com/manual/ référence/opérateur/agrégation/filtre/
https://docs.mongodb.com/manual/ référence/opérateur/agrégation/replaceRoot/