我想在 gremlin 中交叉 2 个聚合集合

I want to intersect 2 aggregated collections in gremlin

我有一个复杂的场景,其中一些间接权限可以被直接关联的权限覆盖。

所以基本上 Role 可以根据他的指定允许 A、B、C 操作 但是特殊权限也可以附加到用户。所以假设特殊权限仅授予操作 A、D。

所以最终他可以只执行动作A

而且他无法执行 B、C、D,因为两者都不可用。

我也写了一个带有其他一些注意事项的查询。

我卡在了 2 个聚合结果的交集处。

 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')
  

我想将 pballow 和 pallow 相交

示例数据和书面查询已在以下 link.

上可用

https://gremlify.com/cmr4i3z3ckh/4

所以那个结果应该只是 id:3899.

你可以做一些 Gremlin 集合操作来得到你的答案。

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')
==>[pballow:[[v[14]]],pallow:[[v[10],v[12],v[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() 创建 side-effect。似乎 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]