Mongodb:只获得树叶

时间:2017-11-07 16:44:05

标签: node.js mongodb tree

我在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

我可以获得完整列表然后删除'group'元素,但那不是很聪明,不是吗?

编辑,因为问题过于简单:
谢谢Wan,下面提供的解决方案回答了我问的问题,以防结构中的元素有一个字段'parent',其中包含父项的路径。 在我的情况下,我有一个字段'父级',但它包含父级的 id ,而不是路径

接下来的问题是你如何connectToField修改字段?在我的情况下,我想连接到#hierarchy of parent#id of parent

而不是连接到字段父

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

1 个答案:

答案 0 :(得分:0)

如果添加字段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中使用树数据结构。根据您的使用情况,您应该使用某些结构来查询您的应用程序的好处。