Jeff
Jeff

Reputation: 127

How can I get the combined script result for janusgraph?

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

Answers (2)

Daniel Kuppitz
Daniel Kuppitz

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

David
David

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

Related Questions