2017-05-31 142 views
1

我正在使用IBM图并使用gremlin尝试过滤某些顶点。我的边有两个标签,可选。这种情况:如何使用gremlin/IBM graph来排除基于边缘的顶点

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

假设这是你的图表:

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()not(without(...))eq()只是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')))过滤器会立即过滤更好顶点出来,你不必等待所有边的计数。

+0

你的假设是正确的。本来希望添加一个示例图,但不知道我会如何去做这件事。我们花了很多时间尝试一些类似的东西,但无法使其发挥作用。用你的解决方案就可以。感谢您的建议,我认为这改善了我们的查询。 – Mischa