MongoDB递归查询顶级父对象

时间:2017-09-20 15:08:54

标签: mongodb

我有一系列地点,想要检索一个顶级父位置。 例如,如果我按ID 4查询位置,则应返回ID为1的位置。

{_id: "1", "parentLocationID": null, "childLocationIds": [2]}
{_id: "2", "parentLocationID": "1", "childLocationIds": [3]}
{_id: "3", "parentLocationID": "2", "childLocationIds": [4]}
{_id: "4", "parentLocationID": "3", "childLocationIds": []}

我目前的解决方案是从后端递归查询db,直到 parentLocationID 为空。 我想做的是将递归处理移到Mongo。 我发现Mongo支持$graphLookup的递归查询,这就是我的开始:

db.locations.aggregate([
    {
        "$match": {
            "childLocationIds": {"$elemMatch": {"$eq", "4"}}
        }
    },
    {
        "$graphLookup": {
            "from": "locations",
            "startWith: "$childLocationIds",
            "connectFromField": "childLocationIds",
            "connectToField": "childLocationIds",
            "as": "parentLocations"
        }
    }
])

查询仅返回第一级父级。你有什么建议吗?

1 个答案:

答案 0 :(得分:1)

找到解决方案,需要更多管道:

db.locations.aggregate([
    {
        "$match": {
            "_id": "4"
        }
    },
    {
        "$graphLookup": {
            "from": "locations",
            "startWith: "$parentLocationID",
            "connectFromField": "_id",
            "connectToField": "parentLocationID",
            "as": "parentLocations"
        }
    },
    {
        "$unwind": "$parentLocations"
    },
    {
        "$replaceRoot": {
            "newRoot": "$parentLocations"
        }
    },
    {
        "$match": {
            "parentLocationID": null
        }
    }
])

$ match 会找到ID为4的位置,然后 $ graphLookup 会将父对象追加到 parentLocations 属性。剩余的管道用于提取顶层位置。