Search code examples
gremlintinkerpop3azure-cosmosdb-gremlinapi

How can I get all child vertices and its edges (properties for both) recursively using gremlin QL?


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?


Solution

  • 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]]:[]]]]]]