Alter
Alter

Reputation: 1213

How to choose right nodes in janusgraph

I need to all blue nodes or the node that the id match between different nodes in the tree, based on the maximum levels. I have this code

 GraphTraversal<Vertex, Map<String, List>> values = graphDbConnection.getGraphTraversalSource().V()
                .hasLabel('uuid').has('uuid', uuid).emit()
                .repeat(in().choose(values('color').is('blue'), identity(), in()))
                .times(levels)
                .map(or(has('color', 'blue'),
                        has('uuid', uuid)))
                .valueMap('uuid', 'color');

if between one blue node and another blue node are more than 3 or 4 incorrect nodes, the algorithm will left out the last possible one.

For example, with that code, if I ask all blues four levels above from uuid=1 including one, it will returns 1,2,3 and will not returns 4 because between 3 and 4 are 3 black. enter image description here

but for this example it will returns 1,2,3,4 because between 3 and 4 are just one or two incorrect nodes enter image description here

Note: One detail here, if I remove times(levels) call, all blue colors will be shown no matter how many wrong colors are in between but without an stop condition, which is the key.

Upvotes: 1

Views: 179

Answers (1)

Kelvin Lawrence
Kelvin Lawrence

Reputation: 14371

The issue is that when you encounter a black node, as in your second diagram, you do an in, but at the start of each repeat you do another in. So if the node after the blue one is black, it will now be also be emitted. One possible way to fix this is to change the emit along the lines of emit(has('color','blue')) so that only nodes with a blue color are kept.

Here is a simple example that hopefully shows this usage of emit clearly.

g.addV('blue').as('b1').
  addV('red').as('r1').
  addV('blue').as('b2').
  addV('red').as('r2').
  addV('blue').as('b3').
  addE('link').from('b1').to('r1').
  addE('link').from('r1').to('b2').
  addE('link').from('b2').to('r2').
  addE('link').from('r2').to('b3')     

Using this type of a approach you can most likely simplify your query.

gremlin> g.V()
==>v[42762]
==>v[42763]
==>v[42764]
==>v[42765]
==>v[42766]

gremlin> g.V(42762).emit(hasLabel('blue')).repeat(out()).times(4).label()
==>blue
==>blue
==>blue

gremlin> g.V(42762).emit().repeat(out()).times(4).label()
==>blue
==>red
==>blue
==>red
==>blue

Finally here is the same example with the choose step added.

gremlin> g.V(42762).emit(hasLabel('blue')).repeat(out().choose(hasLabel('blue'),identity(),out())).times(2).label()
==>blue
==>blue
==>blue 

Upvotes: 1

Related Questions