如何使用 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'))) 的过滤器将立即过滤掉顶点,您不必等待所有边的计数。