Reputation: 127
Graph is below:
gremlin> a = graph.addVertex("name", "alice")
gremlin> b = graph.addVertex("name", "bobby")
gremlin> c = graph.addVertex("name", "cindy")
gremlin> d = graph.addVertex("name", "david")
gremlin> e = graph.addVertex("name", "eliza")
gremlin> a.addEdge("rates",b,"tag","ruby","value",9)
gremlin> b.addEdge("rates",c,"tag","ruby","value",8)
gremlin> c.addEdge("rates",d,"tag","ruby","value",7)
gremlin> d.addEdge("rates",e,"tag","ruby","value",6)
gremlin> e.addEdge("rates",a,"tag","java","value",10)
I have 3 scripts below:
Script #1
gremlin> g.V().has('name','alice').
repeat(out()).
until(has('name','alice')).
cyclicPath().
path().by('name')`
==>[alice,bobby,cindy,david,eliza,alice]
Script #2
gremlin> g.V().has('name','alice').
repeat(outE().inV()).
until(has('name','alice')).
cyclicPath().
group().
by('name').
by(path().unfold().has('value').values('value').fold()).
next()
==>alice=[9, 8, 7, 6, 10]
Script #3
gremlin> g.V().has('name','alice').
repeat(outE().inV()).
until(has('name','alice')).
cyclicPath().
group().
by('name').
by(path().unfold().has('value').values('value').fold()).
next().collect { k, v ->
k + '=' + v.withIndex().collect { Integer it, Integer idx ->
return it * (1/(idx + 1))
}.inject(0.0) { acc,i -> acc + i }
}
==>alice=18.8333333331
My question is, how can I get the result as below listed? Just combine the 3
alice=[alice,bobby,cindy,david,eliza,alice]=[9, 8, 7, 6, 10]=18.8333333331
Upvotes: 1
Views: 373
Reputation: 10904
It's probably much easier or at least more maintainable to execute 3 queries and then merge the results as suggested by David. However, if you want to do it all in a single query, you can:
g.V().has('name','alice').as('v').
repeat(outE().as('e').inV().as('v')).
until(has('name','alice')).
store('a').
by('name').
store('a').
by(select(all, 'v').unfold().values('name').fold()).
store('a').
by(select(all, 'e').unfold().
store('x').
by(union(values('value'),
select('x').count(local)).fold()).
cap('x').
store('a').
by(unfold().limit(local, 1).fold()).unfold().
sack(assign).
by(constant(1d)).
sack(div).
by(union(constant(1d),
tail(local, 1)).sum()).
sack(mult).
by(limit(local, 1)).
sack().sum()).
cap('a')
Using your sample graph:
gremlin> g.V().has('name','alice').as('v').
......1> repeat(outE().as('e').inV().as('v')).
......2> until(has('name','alice')).
......3> store('a').
......4> by('name').
......5> store('a').
......6> by(select(all, 'v').unfold().values('name').fold()).
......7> store('a').
......8> by(select(all, 'e').unfold().
......9> store('x').
.....10> by(union(values('value'),
.....11> select('x').count(local)).fold()).
.....12> cap('x').
.....13> store('a').
.....14> by(unfold().limit(local, 1).fold()).unfold().
.....15> sack(assign).
.....16> by(constant(1d)).
.....17> sack(div).
.....18> by(union(constant(1d),
.....19> tail(local, 1)).sum()).
.....20> sack(mult).
.....21> by(limit(local, 1)).
.....22> sack().sum()).
.....23> cap('a')
==>[alice,[alice,bobby,cindy,david,eliza,alice],[9,8,7,6,10],18.833333333333332]
It has some benefits to do it all in a single query, especially as you don't have to traverse the same path over and over again, but again, it's hard to maintain such complex queries. It's probably better to just return the full path and then build the expected result on the client side.
Upvotes: 5
Reputation: 506
Gremlin code is executed in a Groovy executor, so all Groovy operators are valid here. You can add your results to a list and return the list, i.e. def l = []; l << result1; l << result2; l;
.
Upvotes: 2