Phoenix
Phoenix

Reputation: 311

Displaying sub-levels in gremlin query

I have the graph as shown in the figure below. The numbers represent the level format of the node which is required as output from the gremlin query along with the properties of the nodes. The graph structure can change that is more nodes can be added to the graph. The level must be returned in a similar format for additional nodes. For example, children of 1.1.1 should return the level as 1.1.1.1,1.1.1.2 ... The following query but the level is in continuous format 1,2,3 ...

g.withSack(0).
  V().
  hasLabel('A').
  has('label_A','A').
  emit().
  repeat(sack(sum).by(constant(1)).out()).
    project('depth', 'properties').
      by(sack()).
      by(valueMap())

A is starting root node.

I know its too complicated. If not possible can we at least get the sub depth along with depth using multiple sack variables. Following is the example:

depth:0 sub-depth:0 depth:1 sub-depth:1.1 depth:1 sub-depth:1.2 depth:2 sub-depth:2.1 depth:2 sub-depth:2.2 depth:2 sub-depth:2.3 depth:2 sub-depth:2.4 enter image description here

Upvotes: 2

Views: 669

Answers (1)

Kelvin Lawrence
Kelvin Lawrence

Reputation: 14371

A simple way to do what you are looking for is to take advantage of the index step. If we create a simple binary tree as follows:

g.addV('root').property('data',9).as('root').   
  addV('node').property('data',5).as('b').   
  addV('node').property('data',2).as('c').   
  addV('node').property('data',11).as('d').   
  addV('node').property('data',15).as('e').   
  addV('node').property('data',10).as('f').   
  addV('node').property('data',1).as('g').   
  addV('node').property('data',8).as('h').   
  addV('node').property('data',22).as('i').   
  addV('node').property('data',16).as('j').   
  addE('left').from('root').to('b').
  addE('left').from('b').to('c').
  addE('right').from('root').to('d').
  addE('right').from('d').to('e').
  addE('right').from('e').to('i').
  addE('left').from('i').to('j').
  addE('left').from('d').to('f').
  addE('right').from('b').to('h').
  addE('left').from('c').to('g').iterate()    

We can combine loops and index as follows (I added the unfold to improve readability):

gremlin> g.V().hasLabel('root').
......1>       emit().
......2>       repeat(group('x').by(loops()).by(values('data').fold().index()).out()).
......3>       cap('x').unfold()   

==>0=[[9, 0]]
==>1=[[5, 0], [11, 1]]
==>2=[[2, 0], [8, 1], [10, 2], [15, 3]]
==>3=[[1, 0], [22, 1]]
==>4=[[16, 0]]

Given your comment about a simpler form being acceptable I think the above gets pretty close. You should be able to tweak this query to make any changes in the output formatting that you require.

You can go one step further and group using the parent vertex as follows. From this you can build whatever projections of the final results you require.

gremlin> g.V().hasLabel('root').
......1>       repeat(outE().group('x').
......2>         by(loops()).
......3>         by(group().
......4>           by(outV()).
......5>           by(inV().values('data').fold().index())).
......6>         inV()).
......7>         times(4).
......8>       cap('x').
......9>       unfold() 

==>0={v[0]=[[5, 0], [11, 1]]}
==>1={v[2]=[[2, 0], [8, 1]], v[6]=[[10, 0], [15, 1]]}
==>2={v[4]=[[1, 0]], v[8]=[[22, 0]]}
==>3={v[16]=[[16, 0]]}       

Upvotes: 1

Related Questions