我有一个树数据结构,其中在叶节点处输入数据。我想要做的是将这些数据汇总到树中,例如对于树中的任何节点,汇总它下面的所有数据。
有没有使用图形数据库的聪明方法来做到这一点?
我有一个树数据结构,其中在叶节点处输入数据。我想要做的是将这些数据汇总到树中,例如对于树中的任何节点,汇总它下面的所有数据。
有没有使用图形数据库的聪明方法来做到这一点?
在 cypher (neo4j) 中,您可以执行以下操作:
start n=node:node_auto_index(id={id})
match n-[:parent_of*]->child
where not(child-[:parent_of]->()) // where the child doesn't have children (leaf)
return n, sum(child.val);
http://wes.skeweredrook.com/cypher-summing-data-up-a-tree-leaf-nodes/
这是使用 Gremlin 的解决方案和刚刚在aureliusgraphs邮件列表中弹出的树数据示例:
g = new TinkerGraph()
root = g.addVertex(['name':'root'])
c1 = g.addVertex(['name':'1', 'sortIndex':1])
c11 = g.addVertex(['name':'1.1', 'sortIndex':1])
c12 = g.addVertex(['name':'1.2', 'sortIndex':2])
c121 = g.addVertex(['name':'1.2.1','sortIndex':1])
c122 = g.addVertex(['name':'1.2.2','sortIndex':2])
c13 = g.addVertex(['name':'1.3', 'sortIndex':3])
c2 = g.addVertex(['name':'2', 'sortIndex':2])
c21 = g.addVertex(['name':'2.1', 'sortIndex':1])
c22 = g.addVertex(['name':'2.2', 'sortIndex':2])
c3 = g.addVertex(['name':'3', 'sortIndex':3])
c31 = g.addVertex(['name':'3.1', 'sortIndex':1])
c32 = g.addVertex(['name':'3.2', 'sortIndex':2])
g.addEdge(root, c1, 'has')
g.addEdge(root, c2, 'has')
g.addEdge(root, c3, 'has')
g.addEdge(c1, c11, 'has')
g.addEdge(c1, c12, 'has')
g.addEdge(c1, c13, 'has')
g.addEdge(c2, c21, 'has')
g.addEdge(c2, c22, 'has')
g.addEdge(c3, c31, 'has')
g.addEdge(c3, c32, 'has')
g.addEdge(c12, c121, 'has')
g.addEdge(c12, c122, 'has')
上面用于初始化图形的代码应该很好地粘贴到Gremlin提示符中。建立图表后,只需发出以下命令即可遍历树并对数值求和(在本例中为 sortIndex 字段):
gremlin> total=0;root.out.sideEffect{total+=it.sortIndex}.loop(2){true}
gremlin> total
==>21
上面的代码初始化了一个total
变量,然后从root
顶点开始遍历,遍历出来再将sortIndex
字段的值加到总数中。然后它在树上循环/重复该操作,直到它耗尽它(最终true
控制它循环多长时间)。
为方便起见,我使用了 TinkerGraph,但此代码可与 Neo4j 或 OrientDB 一起使用(我在此问题上将其视为其他标签),只需将图形实现更改如下:
g = new Neo4jGraph('/tmp/neo4j')
或者
g = new OrientGraph('memory:/graph')