如何编写Gremlin查询以查找具有指定边的父顶点?

时间:2019-01-02 19:34:19

标签: graph-databases gremlin

我是gremlin查询的新手。我有一个如下图,我的源顶点是P3,我想编写一个查询,该查询将获取所有父\祖先顶点(如果该顶点到具有边缘的P3路径,则该顶点是P3的父\祖先顶点类型为“零件”的“包含”),并具有与其相关联的所有者。因此,在这种情况下,查询应返回P1和P2,但不返回P。

查询以创建示例数据:

    g.addV(id, 'P1').property('label','part').as('p1')
.addV(id, 'P2').property('label','part').as('p2')
.addV(id, 'P3').property('label','part').as('p3')
.addV(id, 'P4').property('label','part').as('p4')
.addV(id, 'owner1').property('label','owner').as('o1')
.addV(id, 'owner2').property('label','owner').as('o2')
.addE('contains').from('p1').to('p2')
.addE('contains').from('p2').to('p3')
.addE('contains').from('p4').to('p3')
.addE('owns').from('o1').to('p1')
.addE('owns').from('o2').to('p2')

enter image description here

这是我提出的查询,但是一旦找到与之关联的所有者顶点的零件顶点,遍历就会停止。如何更新它以同时返回P1和P2。

g.V('P3')
           .union(
                            inE().hasLabel('owns').inV(),
                repeat(inE().hasLabel('contains')
                                            .outV().hasLabel('part'))
                                            .until(inE().hasLabel('owns'))
                ).dedup()

我还尝试了使用sideEffect步骤来收集零件顶点,但是没有得到所需的结果。

g.V('P3').union(
inE().hasLabel('owns').inV(),
repeat(inE().sideEffect(hasLabel('owns').outV().as('parts'))
        .hasLabel('contains')
        .outV().hasLabel('part'))
)
.select('parts').dedup()

1 个答案:

答案 0 :(得分:2)

由于语法错误,我对示例数据代码进行了一些修改:

gremlin> g = TinkerGraph.open().traversal()
==>graphtraversalsource[tinkergraph[vertices:0 edges:0], standard]
gremlin> g.addV('part').property(id, 'P1').as('p1').
......1>   addV('part').property(id, 'P2').as('p2').
......2>   addV('part').property(id, 'P3').as('p3').
......3>   addV('part').property(id, 'P4').as('p4').
......4>   addV('owner').property(id, 'owner1').as('o1').
......5>   addV('owner').property(id, 'owner2').as('o2').
......6>   addE('contains').from('p1').to('p2').
......7>   addE('contains').from('p2').to('p3').
......8>   addE('contains').from('p4').to('p3').
......9>   addE('owns').from('o1').to('p1').
.....10>   addE('owns').from('o2').to('p2').iterate()

我认为您可以将遍历简化为简单的repeat()

gremlin> g.V('P3').emit(inE('owns')).repeat(__.in('contains'))
==>v[P2]
==>v[P1]

请注意emit()步骤的位置,该步骤控制从循环输出的顶点。