How to Sum the weight with coefficient in JanusGraph?

298 views Asked by At

We have the Graph below.

gremlin> a = graph.addVertex("name", "alice")
==>v[4208]
gremlin> b = graph.addVertex("name", "bobby")
==>v[40968424]
gremlin> c = graph.addVertex("name", "cindy")
==>v[4192]
gremlin> d = graph.addVertex("name", "david")
==>v[40972520]
gremlin> e = graph.addVertex("name", "eliza")
==>v[40964272]
gremlin> a.addEdge("rates",b,"tag","ruby","value",9)
==>e[2ry-38w-azv9-oe3fs][4208-rates->40968424]
gremlin> b.addEdge("rates",c,"tag","ruby","value",8)
==>e[odzq5-oe3fs-azv9-38g][40968424-rates->4192]
gremlin> c.addEdge("rates",d,"tag","ruby","value",7)
==>e[170-38g-azv9-oe6lk][4192-rates->40972520]
gremlin> d.addEdge("rates",e,"tag","ruby","value",6)
==>e[oe04d-oe6lk-azv9-oe08g][40972520-rates->40964272]
gremlin> a.addEdge("rates",e,"tag","java","value",9)
==>e[366-38w-azv9-oe08g][4208-rates->40964272]
gremlin> g.E().values("tag")
==>ruby
==>ruby
==>ruby
==>ruby
==>java
gremlin> graph.tx().commit()

Below Script we can get the weight for all the paths.

gremlin>g.V().has('name','alice').repeat(outE().has('tag','ruby').inV()).times(3).emit().group().by('name').by(path().unfold().has('value').values('value').fold()).next()
==>bobby=[9]
==>cindy=[8, 9, 8]
==>david=[8, 7, 9, 8, 7]

Below we can sum the weight for all the paths.

gremlin>g.V().has('name','alice').repeat(outE().has('tag','ruby').inV()).times(3).emit().group().by('name').by(path().unfold().has('value').values('value').sum()).next()
==>bobby=9 sum[9]
==>cindy=25 sum[8, 9, 8]
==>david=39 sum[8, 7, 9, 8, 7]

My question is how can I Sum the weight with coefficient? like below

==>bobby=[9] = 9*1
==>cindy=[8, 9, 8] = 8*1 + 9*0.5 + 8*0.25 
==>david=[8, 7, 9, 8, 7] = 8*1 + 7*0.5 + 9*0.25 + 8*0.125 + 7*0.0625

Another request is if the coefficient is from edge property co?

Your help is really appreciated!

2

There are 2 answers

1
pantalohnes On BEST ANSWER

You can do something like g.V().has('name','alice').repeat(outE().has('tag','ruby').inV()).times(3).emit().group().by('name').by(path().unfold().has('value').values('value').fold()).next().collect{k, v -> v.withIndex().collect {Integer it, Integer idx -> return it * (1/(idx + 1))}.inject(0.0) {acc,i -> acc+i}} Don't forget, you're working with the groovy programming language as well, so you have access to those features.

0
Daniel Kuppitz On

Try to prevent lambdas when possible.

gremlin> g.withSack(1.0).V().has("name","alice").
           repeat(outE("rates").has("tag","ruby").
                  project("a","b","c").
                    by(inV()).
                    by(sack()).
                    by("value").as("x").
                  select("a").
                  sack(mult).by(constant(0.5))).
              times(3).emit().
            select(all, "x").
            project("name","score").
              by(tail(local, 1).select("a").values("name")).
              by(unfold().
                 sack(assign).by(select("b")).
                 sack(mult).by(select("c")).
                 sack().sum())
==>[name:bobby,score:9.0]
==>[name:cindy,score:13.00]
==>[name:david,score:14.750]

This query returns a result that differs a bit from your provided example, but that's only because your queries show results, that were not produced using the provided sample graph.