我想在gremlin中相交2个聚合集合
我有一个复杂的场景,其中一些间接权限可以被直接关联的权限覆盖 所以基本上角色可以有A,B,C动作,基于他的指定 但特殊权限也可以附加到用户。所以,让我们假设特殊许可只授予动作A,D 因此,最终他只能执行动作A 他不能执行B、C、D,因为这两种语言都不可用 我写了一个查询,还考虑了其他一些因素 我被困在两个聚合结果的交叉点上我想在gremlin中相交2个聚合集合,gremlin,Gremlin,我有一个复杂的场景,其中一些间接权限可以被直接关联的权限覆盖 所以基本上角色可以有A,B,C动作,基于他的指定 但特殊权限也可以附加到用户。所以,让我们假设特殊许可只授予动作A,D 因此,最终他只能执行动作A 他不能执行B、C、D,因为这两种语言都不可用 我写了一个查询,还考虑了其他一些因素 我被困在两个聚合结果的交叉点上 g.V().hasLabel('r').has('name', 'r1'). as('r'). match( __.as('a'). out('
g.V().hasLabel('r').has('name', 'r1').
as('r').
match(
__.as('a').
out('has pb').out('allow').
where(__.in('deny').
hasLabel('pb').out('deny').
count().is(0)).fold().aggregate('pballow'),
__.as('a').
out('has p').out('allow').
where(__.in('deny').
hasLabel('p').out('deny').
count().is(0)).fold().aggregate('pallow')).
select('pballow','pallow')
我想和帕洛相交
示例数据和书面查询已在以下链接中提供
所以这个结果应该只有id:3899。你可以做一些小精灵集合操作来得到你的答案
g = TinkerGraph.open().traversal()
g.addV('a').as('1').
property(single, 'name', 'a1').addV('r').
as('2').
property(single, 'name', 'r1').addV('r').
as('3').
property(single, 'name', 'r2').addV('p').
as('4').
property(single, 'name', 'p1').addV('pb').
as('5').
property(single, 'name', 'pb1').addV('a').
as('6').
property(single, 'name', 'a1').addV('a').
as('7').
property(single, 'name', 'a2').addV('a').
as('8').
property(single, 'name', 'a3').addV('re').
as('9').
property(single, 'name', 're1').addV('scp').
as('10').
property(single, 'name', 'scp1').addV('al').
as('11').
property(single, 'name', 'l').addV('al').
as('12').
property(single, 'name', 'r').addV('tc').
as('13').
property(single, 'name', 'tc1').addV('s').
as('14').
property(single, 'name', 's1').
addE('has scp').from('1').to('10').
addE('has r').from('1').to('3').addE('has r').
from('1').to('2').addE('has pb').from('2').
to('5').addE('has p').from('2').to('4').
addE('allow').from('4').to('6').addE('allow').
from('4').to('7').addE('allow').from('4').
to('8').addE('allow').from('5').to('8').
addE('deny').from('5').to('6').
addE('of type').from('6').to('11').addE('on').
from('6').to('9').addE('of tc').from('7').
to('13').addE('of type').from('7').to('12').
addE('on').from('7').to('9').addE('of tc').
from('8').to('13').addE('of type').from('8').
to('12').addE('on').from('8').to('9').
addE('asmd').from('9').to('2').addE('of').
from('9').to('14')
在您的例子中,我将在这里展示一个深度嵌套的结果(我在几个地方对代码进行了一些优化):
这种深度嵌套需要进行大量的展开才能解压要相交的顶点,但可以这样做:
gremlin> g.V().has('r','name', 'r1').as('r').
......1> match(
......2> __.as('a').
......3> out('has pb').out('allow').
......4> where(__.not(__.in('deny').
......5> hasLabel('pb').out('deny'))).fold().aggregate('pballow'),
......6> __.as('a').
......7> out('has p').out('allow').
......8> where(__.not(__.in('deny').
......9> hasLabel('p').out('deny'))).fold().aggregate('pallow')).
.....10> select('pballow','pallow').
.....11> select(values).
.....12> unfold().unfold().unfold().
.....13> groupCount().
.....14> unfold().
.....15> where(select(values).is(gt(1))).
.....16> select(keys)
==>v[14]
我认为您可以简化这种遍历,并避免一些解包。我认为没有必要使用match()
、将步骤标记为as()
或使用产生副作用的aggregate()
。似乎union()
可以取代所有这些,并使此遍历更具可读性:
gremlin> g.V().has('r','name', 'r1').
......1> union(out('has pb').out('allow').
......2> where(__.not(__.in('deny').
......3> hasLabel('pb').out('deny'))),
......4> out('has p').out('allow').
......5> where(__.not(__.in('deny').
......6> hasLabel('p').out('deny')))).
......7> groupCount().
......8> unfold().
......9> where(select(values).is(gt(1))).
.....10> select(keys)
==>v[14]
谢谢你的帮助,在这个问题上还有一个相关的问题。我还想创建一条从“r”到该查询输出(结果)的边。我怎样才能在同一个查询中使用addE来达到这个目的呢?好吧,你不能标记你对“r”的第一次引用,因为在
groupCount()
的减少障碍之后,你会失去对它的跟踪,所以我想我应该做:addE('link')。在select(key)
之后加上(V.has('r','name','r1'))
,非常感谢Stephen。在同一个示例图上,我还有另一个问题,我应该很快就会发布这个问题。我也想得到你的解决方案。非常感谢你的帮助。
gremlin> g.V().has('r','name', 'r1').
......1> union(out('has pb').out('allow').
......2> where(__.not(__.in('deny').
......3> hasLabel('pb').out('deny'))),
......4> out('has p').out('allow').
......5> where(__.not(__.in('deny').
......6> hasLabel('p').out('deny')))).
......7> groupCount().
......8> unfold().
......9> where(select(values).is(gt(1))).
.....10> select(keys)
==>v[14]