1

我正在使用 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()

这是最好的方法吗?还是有更聪明的方法?

4

1 回答 1

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

于 2017-05-31T11:49:19.737 回答