0
  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.

Kunal
  • 27
  • 7

1 Answers1

2

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.

stephen mallette
  • 45,298
  • 5
  • 67
  • 135
  • First one works great, thanks for that. For the second, I think my use of coalesce() is incorrect. All I want to do is, out of all the incoming edges to a vertex, choose one at random. So I am able to do this with g.V().has('id',).inE().order().by(shuffle).next(). Is there a better way to do this? – Kunal Jul 17 '18 at 11:43
  • This approach is not working. Consider my earlier question, in the likedByFollowing attribute how could I get only one of them (chosen randomly out of 3,4 or any number of users): https://stackoverflow.com/questions/51334950/graph-gremlin-for-social-media-use-case – Kunal Jul 17 '18 at 14:59
  • it doesn't work if you do: `by(__.in('liked').where(within('followers')).order().by(shuffle))` or `by(__.in('liked').where(within('followers')).sample(1))` either of those should grab a random one (you can drop `fold()` at the end i guess since you only want one (unless you want that one wrapped in a `List` – stephen mallette Jul 17 '18 at 15:06
  • The problem is that the other traversal throws out error that it does not map to a value – Kunal Jul 17 '18 at 16:04
  • i suggest you take your current query that fails between these two questions and and start a new question with a sample Gremlin script that reproduces the problem you are seeing. i'm sorry, but it's really hard to follow the problem otherwise. – stephen mallette Jul 17 '18 at 16:19
  • Ok sorry about that. Made it a new question, I know you have already tried to answer but see if this explains it better: https://stackoverflow.com/questions/51388315/gremlin-choose-one-item-at-random – Kunal Jul 17 '18 at 18:45
  • answered - that helped - sorry, had to see it all as one question. i just couldn't connect it all. – stephen mallette Jul 17 '18 at 18:58