1

I have a tree structure look like this

{ 
    "_id" : ObjectId("59aebe21f002a8556ca78310"), 
    "fid" : ObjectId("59aebe216b96002252a89d7b"), 
    "pr" : [

    ], 
    "ch" : [
        {
            "_id" : ObjectId("59aebe326b96002252a89d7d"), 
            "trashed" : false
        }, 
        {
            "_id" : ObjectId("59aebe376b96002252a89d7f"), 
            "trashed" : false
        }
    ]
}
{ 
    "_id" : ObjectId("59aebe33f002a8556ca78347"), 
    "fid" : ObjectId("59aebe326b96002252a89d7d"), 
    "pr" : [
        {
            "_id" : ObjectId("59aebe216b96002252a89d7b"), 
            "trashed" : false
        }
    ], 
    "ch" : [
        {
            "_id" : ObjectId("59aebe3b6b96002252a89d81"), 
            "trashed" : false
        }
    ]
}

the fid is a folder id and the ch is the children of folder , so I want to do a recursive search to get tree of the folders and files. In my case I have a used $graphLookup to do a recursive search but as a result I am getting other folders too

pipeline := []bson.M{
        {"$match": bson.M{"fid": id}},
        {"$graphLookup": bson.M{
            "from":             "tree",
            "startWith":        "$fid",
            "connectFromField": "fid",
            "connectToField":   "ch._id",
            "as":               "parents",
        }},
        {"$match": bson.M{"ch.trashed": false}},
    }

    Connection.Session.DB("cctv_storage").C("tree").Pipe(pipeline).All(&tData)

My project based on Golang.

1
  • Please read how $graphLookup works: docs.mongodb.com/manual/reference/operator/aggregation/… If "connectToField": "ch._id" then as should really be "children", not "parents". The second $match filters the top-level documents only, not all children/parents. Besides, all of the documents in the example have "ch.trashed": false. Commented Sep 6, 2017 at 9:11

1 Answer 1

1

I think you need to use $unwind for first, than $graphLookup, so you need to do a recursive search look like this

var tData struct {
        Id    bson.ObjectId     `bson:"_id"`
        Child [][]bson.ObjectId `bson:"child"`
    }

pipeline := []bson.M{
        {"$unwind": bson.M{
            "path": "$pr",
            "preserveNullAndEmptyArrays": true,
        }},
        {"$graphLookup": bson.M{
            "from":             "tree",
            "startWith":        "$fid",
            "connectFromField": "fid",
            "connectToField":   "pr._id",
            "as":               "child",
        }},
        {"$match": bson.M{"fid": id}},
        {"$group": bson.M{"_id": id, "child": bson.M{"$addToSet": "$child.fid"}}},
    }
Connection.Session.DB("cctv_storage").C("tree").Pipe(pipeline).One(&tData)

So as a result you will get the id of the root folder and the ids of children

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.