Gremlin use case - Int properties and coalesce()

2019-08-27 14:05发布

  1. Can vertex properties stored as integers be incremented and decremented? If so, how?

  2. For a fixed dataset, does coalesce() always return the same item? Is it possible to randomise it or any other way to do it? For instance of all the incoming vertices, choose a random one every time even if the dataset itself is not changed.

1条回答
在下西门庆
2楼-- · 2019-08-27 14:36

Can vertex properties stored as integers be incremented and decremented?

You can use sack():

gremlin> g = TinkerFactory.createModern().traversal()
==>graphtraversalsource[tinkergraph[vertices:6 edges:6], standard]
gremlin> g.V().property('counter',0).iterate()
gremlin> g.V().
......1>   sack(assign).
......2>     by('counter').
......3>   sack(sum).
......4>     by(constant(1)).
......5>   property('counter', sack()).
......6>   valueMap()
==>[name:[marko],counter:[1],age:[29]]
==>[name:[vadas],counter:[1],age:[27]]
==>[name:[lop],counter:[1],lang:[java]]
==>[name:[josh],counter:[1],age:[32]]
==>[name:[ripple],counter:[1],lang:[java]]
==>[name:[peter],counter:[1],age:[35]]
gremlin> g.V().
......1>   sack(assign).
......2>     by('counter').
......3>   sack(sum).
......4>     by(constant(1)).
......5>   property('counter', sack()).
......6>   valueMap()
==>[name:[marko],counter:[2],age:[29]]
==>[name:[vadas],counter:[2],age:[27]]
==>[name:[lop],counter:[2],lang:[java]]
==>[name:[josh],counter:[2],age:[32]]
==>[name:[ripple],counter:[2],lang:[java]]
==>[name:[peter],counter:[2],age:[35]]

Let's look at the traversal more closely now that you've seen it in action above:

g.V().
  sack(assign).
    by('counter').
  sack(sum).
    by(constant(1)).
  property('counter', sack()).
  valueMap()

So for each vertex, you place a value in its "sack" with assign - the by('counter') modulator defines that assignment as the value of the "counter" property (which was initialized to zero earlier in my example). Then with sack(sum) we define how we increment the counter by(constant(1)) or "by 1" (i.e. take the value in the sack and sum it together with 1 and store that value in the sack). Finally we take the value out of the sack and overwrite the original "counter" property with the new value with property('counter', sack()).

For a fixed dataset, does coalesce() always return the same item?

Most questions that pertains to "element order" must be deferred to the underlying graph system. If your graph database returns elements in a deterministic order then your Gremlin should. If you need to be sure of an order and have a completely portable query then you should include use of order() step in Gremlin.

I believe that coalesce will always go with the first traversal to return a value, so in:

g.V().coalesce(outE(), inE())

you will always get the result of outE() if the current vertex has outgoing edges. To get a random choice out maybe you could do something like:

g.V().coalesce(outE().fold().coin(0.5), inE().fold()).unfold()

That kinda works...in other words, for cases where outE() returns something, 50% of the time it would return nothing and thus allow the inE() option to work. I'm not sure exactly what you're after but perhaps you can get coalesce() out of the equation and just use simple coin(), sample(), etc to solve your problem.

查看更多
登录 后发表回答