【问题标题】:Mongodb: get only leaves of treeMongodb:只获取树叶
【发布时间】:2017-11-10 17:15:33
【问题描述】:

我在 mongo 数据库中有一个树结构来满足我的需要。树节点由其路径标识:根节点路径为

#<id>

子节点在其路径中描述其完整的层次结构:

#<id of parent>#<id of parent>#<id>

例如,我可以拥有以下树:

#a
|_#a#b
|    |_#a#b#1
|    |_#a#b#2
|_#a#c
    |_#a#c#1
          |_#a#c#1#x

我目前的方法是使用 $regex 获取树节点的所有子节点。应用到

#a#c

在这种情况下会返回以下节点

#a#c#1
#a#c#1#x

现在我正试图找到一种方法来只找到我的树的叶子。所以将它应用到同一个节点我只会得到:

#a#c#1#x

我可以获取完整列表,然后删除“组”元素,但这并不聪明,不是吗?

编辑,因为问题过于简单:
谢谢万,下面提供的解决方案回答了我在结构中的元素有一个包含父级路径的字段“父级”时提出的问题。 就我而言,我有一个字段“父”,但它包含父的 id,而不是它的 路径

下一个问题是你如何connectToField 来修改字段?就我而言,我不想连接到字段父级,而是想连接到#hierarchy of parent#id of parent

是否可以对查询结果进行某种形式的预格式化,以便 parent 包含路径而不是 id?

【问题讨论】:

    标签: node.js mongodb tree


    【解决方案1】:

    如果您添加一个字段parent 来捕获每个节点的父节点,它可能有助于优化对更大数据集的查询。例如:

    {"parent": "", "node": "#a"}
    {"parent": "#a", "node": "#a#b"}
    {"parent": "#a", "node": "#a#c"}
    {"parent": "#a#b", "node": "#a#b#1"}
    {"parent": "#a#b", "node": "#a#b#2"}
    {"parent": "#a#c", "node": "#a#c#1"}
    {"parent": "#a#c#1", "node": "#a#c#1#x"}
    

    然后就可以使用$graphLookup (aggregation)操作符进行遍历了。

    获取#a#c 的树节点的所有子节点的正则表达式查询的替代方法:

    db.tree.aggregate([
            {$match:{"node":"#a#c"}}, 
            {$graphLookup:{
                           from:"tree", 
                           startWith:"$node", 
                           connectFromField:"node", 
                           connectToField:"parent", 
                           as:"dep"}}, 
            {$project:{"dep.node":1, "_id":0}}
    ])
    

    只查找#a#c的叶子:

    db.tree.aggregate([
            {$match:{"parent": {$regex:"^#a#c"}}}, 
            {$graphLookup:{
                           from:"tree", 
                           startWith:"$node", 
                           connectFromField:"node", 
                           connectToField:"parent", 
                           as:"dep"}}, 
            {$match:{dep:[]}}, 
            {$project:{"_id":0, node:1}}
    ])
    

    我还建议查看Model Tree Structures,在 MongoDB 中有多种使用树数据结构的方法。根据您的用例,您应该为您的应用程序查询优势采用某些结构。

    【讨论】:

    • 感谢您的回答,我实际上已经在每个节点上都有一个父字段。我将仔细研究 $graphLookup 并了解如何从中受益。
    • 好的,我尝试了您提出的解决方案,它非常适合我提出的问题。现在我不得不让它变得更加困难,因为我过度简化了我的问题。我确实有一个父字段,但它不包含父项的路径,它包含父项的名称。我将编辑问题
    • @BriceMaret 我认为最好发布一个新问题并将帖子链接到此处而不是更改问题。
    • 谢谢你,我按照你的建议做了stackoverflow.com/questions/47270370/…
    猜你喜欢
    • 1970-01-01
    • 2015-10-01
    • 1970-01-01
    • 2016-05-25
    • 2021-01-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多