我正在使用IBM图表并使用gremlin尝试过滤某些顶点。我的边缘有两个标签和可选。这种情况:
V3 -- V5 -- V6
/ \
V1 \
\ \
V2 -- V4
这有点像供需链。 V1是提供两种电源(V3和V2)的对象。 V4需要两种供应才能工作。 V5需要V3和V6才能工作。因为我只有V2和V3。我需要一个查询,允许我从V2和V3移动到每个传出顶点,但根据该顶点是否具有所需的边(但允许可选边)来排除顶点。
经过多次尝试,这是同事提出的:
def g = graph.traversal(); g.V(1).out().outE().aggregate('edges').inV().where(inE('required').where(not(within('edges'))).count().is(eq(0))).dedup()
这是最好的方法吗?或者有更聪明的方法吗?
答案 0 :(得分:4)
假设这是你的图表:
gremlin> g.addV().property(id,1).as('1').
......1> addV().property(id,2).as('2').
......2> addV().property(id,3).as('3').
......3> addV().property(id,4).as('4').
......4> addV().property(id,5).as('5').
......5> addV().property(id,6).as('6').
......6> addE('supplies').from('1').to('2').
......7> addE('supplies').from('1').to('3').
......8> addE('required').from('2').to('4').
......9> addE('required').from('3').to('4').
.....10> addE('required').from('3').to('5').
.....11> addE('required').from('6').to('5').iterate()
这是预期的输出:
gremlin> g.V(1).
......1> out().
......2> outE().
......3> aggregate('edges').
......4> inV().
......5> where(inE('required').
......6> where(not(within('edges'))).
......7> count().is(eq(0))).
......8> dedup()
==>v[4]
然后聚合边缘已遍历边缘可能是最好的方法。 (在您的问题中,最好将示例图表作为Gremlin脚本包含在内。)我认为值得注意的是,您不需要eq()
中的is()
和not(without(...))
只是without
:
gremlin> g.V(1).
......1> out().
......2> outE().
......3> aggregate('edges').
......4> inV().
......5> where(inE('required').
......6> where(without('edges')).
......7> count().is(0)).
......8> dedup()
==>v[4]
或者只是不再计算所有数据,因为你想要那些没有返回新边的顶点来遍历:
gremlin> g.V(1).
......1> out().
......2> outE().
......3> aggregate('edges').
......4> inV().
......5> not(inE('required').
......6> where(without('edges'))).
......7> dedup()
==>v[4]
上述方法可能会更好,因为只有一个边缘立即返回
您的inE('required').where(not(within('edges')))
过滤器会立即过滤掉顶点,您不必等待所有边缘的计数。