non-trivial
です ソリューション。
要件
1フィールドを追加する必要があります(level
と呼びましょう) )これは、ドキュメントが階層内のどこにあるかを示します。
|root 0
|-child A 1
|--child A_1 2
|-child B 1
2define
する必要があります 以前の階層の深さ(例:最大3)
制限
特定のレベルからフィルタリングするには、root
を変更する必要があります およびchildren
$ match 値。
常に階層レベルを確保する:
root - 0
children - 1
root - 1
children - 2
解決策
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 (最大深度:3)| MongoPlayground (最大深度:4)
説明
-
$facet
を使用 レベル構造を定義します。root
すべてのルートディレクトリのみ。children
レベル1以上の子孫を持つすべての子が含まれます。 -
$filter
(マージ)parentId
によるルートと子 -
$project
を使用 および$replaceRoot
元の構造を返します。
リンク
https://docs.mongodb.com/manual/reference/operator/アグリゲーション/ファセット/
https://docs.mongodb.com/manual/参照/演算子/集計/フィルター/
https://docs.mongodb.com/manual/参照/演算子/集約/replaceRoot/