私は、ツリー構造でのMongoDBにおける文書のリストを持っている親の参照を持つモデルツリー構造パターンを使用しました。私は、「名前」プロパティ与えられ、(ルートまで)の祖先のリストを返す単一の集約クエリをしたいです。
構造:
{
'_id': '1',
'name': 'A',
'parent': '',
},
{
'_id': '2',
'name': 'B',
'parent': 'A',
},
{
'_id': '3',
'name': 'C',
'parent': 'B',
},
{
'_id': '4',
'name': 'D',
'parent': 'C',
}
集計結果:(与えられた、名前= 'D')
{
'_id': '4',
'name': 'D',
'ancestors': [{name:'C'}, {name:'B'}, {name:'A'}]
}
Note:
現在、ドキュメントの構造を変更できません。それは多くの問題を引き起こします。祖先の配列でモデルツリー構造を使用することを提案する多くのソリューションを見ました。しかし、私は今それを使用することはできません。単一の集計クエリを使用して上記のパターンでそれを達成する方法はありますか?ありがとうございました
MongoDB 3.4以降、これはAggregationFrameworkで実行できます。
パイプラインの最初で最も重要なステージは$graphLookup
ステージです。$graphLookup
「親」フィールドと「名前」フィールドを再帰的に照合できます。その結果、各「名前」の祖先を取得します。
パイプラインの次の段階は、$match
関心のある「名前」を選択するだけの段階です。
最終段階である$addFields
か、$project
我々が使用して「先祖」配列に式を適用する段階$map
配列演算子。
もちろん、$reverseArray
演算子を使用して、期待される結果を得るために配列を逆にします。
db.collection.aggregate(
[
{ "$graphLookup": {
"from": "collection",
"startWith": "$parent",
"connectFromField": "parent",
"connectToField": "name",
"as": "ancestors"
}},
{ "$match": { "name": "D" } },
{ "$addFields": {
"ancestors": {
"$reverseArray": {
"$map": {
"input": "$ancestors",
"as": "t",
"in": { "name": "$$t.name" }
}
}
}
}}
]
)
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加