如何计算Gremlin中子树的聚合?

iso*_*tel 10 tree aggregate gremlin

我有一个具有多个级别的树,其中叶节点可能具有属性"count".我想计算每个子树的总计数,并将这些值缓存在每个子树的根节点中.这可能在Gremlin?

ste*_*tte 5

您可以使用sideEffect- 做到这一点很简单。我们用以下命令设置一个简单的树:

gremlin> g = new TinkerGraph()                                                                 
==>tinkergraph[vertices:0 edges:0]
gremlin> v1 = g.addVertex()                                                                    
==>v[0]
gremlin> v2 = g.addVertex()                                                                    
==>v[1]
gremlin> v3 = g.addVertex([count:2])                                                           
==>v[2]
gremlin> v4 = g.addVertex([count:3])                                                           
==>v[3]
gremlin> v1.addEdge('child',v2)                                                                
==>e[4][0-child->1]
gremlin> v1.addEdge('child',v3)                                                                
==>e[5][0-child->2]
gremli                                                                                         
gremlin> v2.addEdge('child',v4)
==>e[6][1-child->3]
Run Code Online (Sandbox Code Playgroud)

然后是整个树中每个子树的计算:

gremlin> g.V().filter{it.outE().hasNext()}.sideEffect{                                           
gremlin>   c=0;                                                                                  
gremlin>   it.as('a').out().sideEffect{leaf -> c+=(leaf.getProperty('count')?:0)}.loop('a'){true}.iterate()
gremlin>   it.setProperty('total',c)                                                                       
gremlin> }                                                                                                 
==>v[0]
==>v[1]
gremlin> g.v(0).total
==>5
gremlin> g.v(1).total                                                                                      
==>3
Run Code Online (Sandbox Code Playgroud)

该查询会像这样分解。首先,这块:

g.V().filter{it.outE().hasNext()}
Run Code Online (Sandbox Code Playgroud)

获取树的任何不是叶节点的部分(即,至少应有一个出站边缘而不是叶)。其次,我们sideEffect用来处理子树的每个根:

it.as('a').out().sideEffect{leaf -> c+=(leaf.getProperty('count')?:0)}.loop('a'){true}.iterate()
Run Code Online (Sandbox Code Playgroud)

将每个子树的“ count”属性的总和存储在名为的变量中c。elvis运算符(?:)有点古怪的优点,可以检查没有“ count”属性的顶点,并在这种情况下返回零。遍历树以进行计算后,c您可以通过以下方式将的值存储c在子树的根节点中:

it.setProperty('total',c) 
Run Code Online (Sandbox Code Playgroud)