如何使用gremlin/IBM graph排除基于边的顶点

如何使用gremlin/IBM graph排除基于边的顶点,gremlin,ibm-graph,Gremlin,Ibm Graph,我正在使用IBM graph并使用gremlin尝试过滤某些顶点。“我的边”有两个必需标签和可选标签。这种情况如下: V3 -- V5 -- V6 / \ V1 \ \ \ V2 -- V4 这有点像供需链。V1是一个提供两种类型的供应V3和V2的对象。V4需要两个电源才能工作。V5需要V3和V6才能工作。因为我只有V2和V3。我需要一个查询,允许我从V2和V3移动到每个传出顶点,但根据该顶点是否具有所需的边(但允许可选边)排除该顶点 经过多次尝试,一位同事得

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

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

假设这是您的图表:

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]
然后,聚合已经遍历的边可能是最好的方法。最好在你的问题中加入一个样本图作为小精灵脚本。我想值得一提的是,你不需要在你的is中使用eq,而不是没有。。。只是没有:

或者干脆不要一起计数,因为您希望遍历那些不返回新边的顶点:

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过滤器是“必需的”。wherenotwithin“edges”将立即过滤掉顶点,您无需等待所有边的计数。

假设这是您的图形:

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]
然后,聚合已经遍历的边可能是最好的方法。最好在你的问题中加入一个样本图作为小精灵脚本。我想值得一提的是,你不需要在你的is中使用eq,而不是没有。。。只是没有:

或者干脆不要一起计数,因为您希望遍历那些不返回新边的顶点:

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过滤器是“必需的”。wherenotwithin“edges”将立即过滤掉顶点,你不必等待所有边的计数。

你的假设是正确的。我很想添加一个示例图,但不确定我将如何进行此操作。我们花了很多时间尝试类似的东西,但都没能成功。使用您的解决方案,它就可以正常工作。谢谢你的建议,我认为这改进了我们的查询。你的假设是正确的。我很想添加一个示例图,但不确定我将如何进行此操作。我们花了很多时间尝试类似的东西,但都没能成功。使用您的解决方案,它就可以正常工作。谢谢你的建议,我想这会改进我们的查询。