如何使用 gremlin/IBM 图排除基于边的顶点
how to exclude vertices based on edges using gremlin/IBM graph
我正在使用 IBM 图形并使用 gremlin 来尝试过滤某些顶点。我的边缘有两个标签需要和可选。这种情况:
V3 -- V5 -- V6
/ \
V1 \
\ \
V2 -- V4
这有点像 supply/demand 链。 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()
这是最好的方法吗?还是有更聪明的方法?
假设这是你的图表:
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 脚本。)我想值得注意的是你不需要 is()
中的 eq()
并且 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]
或者干脆取消全部计数,因为您希望那些 return 没有新边可遍历的顶点:
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]
上述方法可能更好,因为直接 return 来自
inE('required').where(not(within('edges')))
的过滤器将立即过滤掉顶点,您不必等待所有边的计数。
我正在使用 IBM 图形并使用 gremlin 来尝试过滤某些顶点。我的边缘有两个标签需要和可选。这种情况:
V3 -- V5 -- V6
/ \
V1 \
\ \
V2 -- V4
这有点像 supply/demand 链。 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()
这是最好的方法吗?还是有更聪明的方法?
假设这是你的图表:
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 脚本。)我想值得注意的是你不需要 is()
中的 eq()
并且 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]
或者干脆取消全部计数,因为您希望那些 return 没有新边可遍历的顶点:
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]
上述方法可能更好,因为直接 return 来自
inE('required').where(not(within('edges')))
的过滤器将立即过滤掉顶点,您不必等待所有边的计数。