如何编写 Gremlin 查询来查找具有指定边的父顶点?
How to write Gremlin query to find parent vertices which have a specified edge?
我是 gremlin 查询的新手。我有一个如下图,我的源顶点是 P3,我想编写一个查询来获取所有 parent\ancestor 顶点(如果有从该顶点的路径,则顶点是 P3 的 parent\ancetor到具有 'contains') 类型 'Part' 类型边的 P3,并有一个 Owner 与之关联。所以在这种情况下,查询应该 return 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')
这是我想出的查询,但是一旦找到具有与之关联的所有者顶点的部分顶点,遍历就会停止。如何将其更新为 return 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()
由于语法错误,我稍微修改了您的示例数据代码:
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()
步骤的位置,该步骤控制从循环输出的顶点。
我是 gremlin 查询的新手。我有一个如下图,我的源顶点是 P3,我想编写一个查询来获取所有 parent\ancestor 顶点(如果有从该顶点的路径,则顶点是 P3 的 parent\ancetor到具有 'contains') 类型 'Part' 类型边的 P3,并有一个 Owner 与之关联。所以在这种情况下,查询应该 return 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')
这是我想出的查询,但是一旦找到具有与之关联的所有者顶点的部分顶点,遍历就会停止。如何将其更新为 return 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()
由于语法错误,我稍微修改了您的示例数据代码:
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()
步骤的位置,该步骤控制从循环输出的顶点。