2

I found query below which is perfect to get all child vertices and edges along with their properties for a given single vertex

g.V().has("name","gremlin").outE().as('e').inV().as('v').select('e','v').by(valueMap())

However how do I do the above recursively, i.e. for a given vertext, it will go through all its children and return each (vertex) and its outgoing edge(s) with all their properties (vertex and edges)....i.e. something like above but in a loop for each of the child vertex it finds....is there a way to do that using gremlin?

noam621
  • 2,766
  • 1
  • 16
  • 26
nDev
  • 97
  • 2
  • 9

1 Answers1

3

Gremlin has a repeat() step that you can use for exactly that. You can do repeat...until and repeat....times and more. The documentation has good examples. located here: https://tinkerpop.apache.org/docs/current/reference/#repeat-step

For example

g.V().has("name","gremlin").
      repeat(outE().inV()).times(2).
      path().
        by(valueMap())

Note that returning all properties using valueMap is a bit like doing SELECT * in SQL and in general it is better to return only what you really need if a result set is large.

If you wanted to get back a tree rather than a set of path results you can use the tree step. Below is an example using TinkerGraph and a simple binary tree graph.

graph=TinkerGraph.open()
g=graph.traversal()

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').
  addV('node').property('data',7).as('k').
  addV('node').property('data',51).as('l').  
  addV('node').property('data',13).as('m'). 
  addV('node').property('data',4).as('n'). 
  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('h').to('k').
  addE('right').from('i').to('l').
  addE('left').from('e').to('m').
  addE('right').from('c').to('n').
  addE('left').from('c').to('g').iterate()

gremlin> g.V().hasLabel('root').repeat(outE().inV()).times(2).tree()

==>[v[0]:[e[28][0-left->2]:[v[2]:[e[35][2-right->14]:[v[14]:[]],e[29][2-left->4]:[v[4]:[]]]],e[30][0-right->6]:[v[6]:[e[3
4][6-left->10]:[v[10]:[]],e[31][6-right->8]:[v[8]:[]]]]]]

gremlin> g.V().hasLabel('root').repeat(outE().inV()).times(2).
               tree().by(valueMap())

==>[[data:[9]]:[[]:[[data:[5]]:[[]:[[data:[8]]:[],[data:[2]]:[]]],[data:[11]]:[[]:[[data:[15]]:[],[data:[10]]:[]]]]]]

gremlin> g.V().hasLabel('root').repeat(outE().inV()).times(2).
               tree().by(valueMap().with(WithOptions.tokens))

    ==>[[id:0,label:root,data:[9]]:[[id:28,label:left]:[[id:2,label:node,data:[5]]:[[id:35,label:right]:[[id:14,label:node,da
    ta:[8]]:[]],[id:29,label:left]:[[id:4,label:node,data:[2]]:[]]]],[id:30,label:right]:[[id:6,label:node,data:[11]]:[[id:34
    ,label:left]:[[id:10,label:node,data:[10]]:[]],[id:31,label:right]:[[id:8,label:node,data:[15]]:[]]]]]]
Kelvin Lawrence
  • 14,674
  • 2
  • 16
  • 38
  • Hi, yes I saw that subsequently in your comprehensive book. Using above, I do not see what I was expecting Say my hierarchy is two deep, A->e1->B, A->e2->C and C->e3->D (i.e. A has two children, B and C and C has child D, e being edges) the above gives me something like [A, e1, C, e3, D] I was expecting it to give me starting from A its edge with B then its edge with C and then C and its edge with D (including vertexes ofcourse)...i.e. the full tree....something I haven't understood well! – nDev May 15 '20 at 09:17
  • 1
    OK so Gremlin has two steps called tree() and subgraph() that are helpful here. Note that what you are seeing is the path from each traverser that walked your graph, it is not a combined result. If you want a combined result take a look at tree(). I will add to the example above. – Kelvin Lawrence May 15 '20 at 12:45
  • Kelvin, thanks that has increased my knowledge a bit more (I haven't been through your book yet!). I can use tree but I see that when I say "times(2)" it only gives me edges which get me to the second level of the tree. It does not give me the first level. So essentially, if I don't know the depth (i.e. cannot do times(x)) then how do I get the output of the entire tree with nodes and its children and edges back? I suspect I can still use tree()? MAny thanks – nDev May 15 '20 at 16:07
  • What i am trying to do is get an entire tree back in a single query. Where I can access each vertex its edges and children. without having to write a nested for loops for each vertex and so on.! Thanks – nDev May 15 '20 at 16:41
  • 2
    If you want to keep traversing until you hit a leaf node you can just replace the times(2) that I just used as an example with something like until(not(out())) – Kelvin Lawrence May 18 '20 at 17:55