如何使用gremlinql递归地获取所有子顶点及其边(两者的属性)?

如何使用gremlinql递归地获取所有子顶点及其边(两者的属性)?,gremlin,tinkerpop3,azure-cosmosdb-gremlinapi,Gremlin,Tinkerpop3,Azure Cosmosdb Gremlinapi,我发现下面的查询非常适合获取给定单个顶点的所有子顶点和边及其属性 g.V().has("name","gremlin").outE().as('e').inV().as('v').select('e','v').by(valueMap()) 但是,我如何递归地执行上述操作,即对于给定的vertext,它将遍历其所有子对象,并返回每个(顶点)及其输出边及其所有属性(顶点和边)…即。类似于上面的内容,但在它找到的每个子顶点的循环中……有没有一种方法可以使用gremlin来实现这一点?gremlin

我发现下面的查询非常适合获取给定单个顶点的所有子顶点和边及其属性

g.V().has("name","gremlin").outE().as('e').inV().as('v').select('e','v').by(valueMap())
但是,我如何递归地执行上述操作,即对于给定的vertext,它将遍历其所有子对象,并返回每个(顶点)及其输出边及其所有属性(顶点和边)…即。类似于上面的内容,但在它找到的每个子顶点的循环中……有没有一种方法可以使用gremlin来实现这一点?

gremlin有一个
repeat()
步骤,您可以使用它来实现这一点。你可以重复……直到……再重复……多次。文档中有很好的示例。 位于此处:

比如说

g.V().has("name","gremlin").
      repeat(outE().inV()).times(2).
      path().
        by(valueMap())
请注意,使用
valueMap
返回所有属性有点像在SQL中执行
SELECT*
,通常,如果结果集很大,最好只返回真正需要的属性

如果您想返回一棵树而不是一组
路径
结果,可以使用
步骤。下面是一个使用TinkerGraph和一个简单的二叉树图的示例

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

嗨,是的,我后来在你的综合书中看到了。使用上面的方法,我看不出我期望的是什么,比如说我的层次结构是两层的,A->e1->B,A->e2->C和C->e3->D(即A有两个子,B和C,C有子D,e是边)上面给了我类似于[A,e1,C,e3,D]的东西,我期望它从A开始,它的边是B,然后它的边是C,然后它的边是C,它的边是D(当然包括顶点)…也就是完整的树…我还不太了解!好吧,所以Gremlin有两个步骤,分别称为tree()和subgraph(),在这里很有用。请注意,您看到的是遍历图形的每个遍历器的路径,它不是一个组合结果。如果您想要一个组合结果,请查看tree()。我将添加到上面的示例中。开尔文,谢谢这增加了我的知识(我还没有读过你的书!)。我可以使用tree,但我发现当我说“times(2)”时,它只会给我边缘,让我进入树的第二层。它不会给我第一层。所以本质上,如果我不知道深度的话(即不能执行次数(x)),那么如何获得包含节点及其子节点和边的整个树的输出?我怀疑我仍然可以使用tree()?许多感谢我尝试在一个查询中返回整个树。在这里我可以访问每个顶点及其边和子节点。无需为每个顶点编写嵌套for循环等等!感谢如果你想继续遍历,直到你碰到一个叶节点,你只需替换次数(2)我刚才用它作为例子,比如until(not(out()))