Mongodb递归搜索对象数组

时间:2017-09-06 08:03:58

标签: mongodb go aggregation-framework

我的树结构看起来像这样

{ 
    "_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
        }
    ]
}
fid 是文件夹ID, ch 是文件夹的子项,因此我想进行递归搜索以获取文件夹和文件的树。 在我的情况下,我有一个使用$graphLookup进行递归搜索,但结果我也得到了其他文件夹

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)

我的项目基于Golang。

1 个答案:

答案 0 :(得分:1)

我认为您需要首先使用$unwind,而不是$graphLookup,因此您需要执行递归搜索,如下所示

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)

因此,您将获得根文件夹的 id 子项

的ID