2017-01-09 14 views
1

たとえば、次のようなツリー構造。MongoDBを使用してツリー構造を再帰的にクエリする方法はありますか?

[ 
    {id: 1 , childrenIdList: [2, 3]}, 
    {id: 2 , childrenIdList: [4, 5]}, 
    {id: 3 , childrenIdList: []}, 
    {id: 4 , childrenIdList: [6, 7]}, 
    {id: 5 , childrenIdList: []}, 
    {id: 6 , childrenIdList: []}, 
    {id: 7 , childrenIdList: []} 
] 

;

   1 
      2  3 
     4 5 
    6 7 

リーフノード(ID = 7)からルート(ID = 1)にツリーをトレースするにはどうすればよいですか?

id=7の親を見つけることは簡単です。

db.document.find({childrenList: { $in: [7]}}, {id: 1}).toArray(function(err), result{ 
    /*result gives 
    {"id" : NumberInt(4)} 
    now I should look the parent of id=4, and parent of id=2 as you know. 
    */ 
}) 

mongodbで再帰的クエリが可能ですか?どのように実装できますか?

+0

グラフのデータをご覧ください:https://www.compose.com/articles/graph-data-with-mongodb/ – Zlatko

答えて

4

MongoDB v3.4は、というaggregation pipelineオペレータを提供します。集約演算子は、コレクションに対して再帰的検索を実行することができます。 $graphLookup definitionの詳細については、こちらをご覧ください。

例として上にドキュメントの階層と値を使用して、集計の下に実行してみてください可能性が:

db.collectionName.aggregate([ 

       {$unwind:{ 
         path:"$childrenIdList", 
         preserveNullAndEmptyArrays: true} 
        }, 
       {$graphLookup:{ 
         from:"collectionName", 
         startWith:"$_id", 
         connectFromField:"_id", 
         connectToField:"childrenIdList", 
         as:"myparents", 
         restrictSearchWithMatch: {"_id"}} 
        }, 
       {$match: {"_id": 7 } }, 
       {$group:{ 
         _id:"$_id", 
         parents:{$addToSet:"$myparents._id"} 
        }} 
]); 

上記のように、以下の結果を返す必要があります。

{ "_id" : 7, "parents" : [ [ 1, 2, 4 ] ] } 

ことを言いました大規模なコレクションをお持ちの場合は、各文書に$unwindを実行しているため、上記のクエリは効果がない可能性があります。索引を利用する。他の人が示唆するように、ドキュメントモデルの構造を再検討する必要があります。 Data Models Tree Structuresを参照してください。アプリケーションロジックに基づいて最適化し、ユースケースをクエリし、柔軟なドキュメントスキーマをフォローできます。

0

再帰的なクエリはできません。コード内でfindを再帰的に呼び出すようにコーディングする必要があります。あるいは、スキーマを再設計して、親のIDを子に、またはすべての祖先を配列またはマテリアライズドパスとして保持することができます。

ツリー構造のデータについては、すでにMongoDBによって提供されているdocumentationを参照してください。

関連する問題