过滤由 Gremlin 遍历和 Groovy 生成的列表
Filter the list generated by a Gremlin traversal and Groovy
我正在进行以下遍历:
g.V().has('Transfer','eventName','Airdrop').as('t1').
outE('sent_to').
inV().dedup().as('a2').
inE('sent_from').
outV().as('t2').
where('t1',eq('t2')).by('address').
outE('sent_to').
inV().as('a3').
select('a3','a2').
by('accountId').toList().groupBy { it.a3 }.collectEntries { [(it.key): [a2 : it.value.a2]]};
正如您所看到的,我基本上是在进行遍历,最后我使用 groovy 和 collectEntries 来聚合我需要的结果,在这种情况下由 a3 聚合。结果如下所示:
==>0xfe43502662ce2adf86d9d49f25a27d65c70a709d={a2=[0x99feb505a8ed9976cf19e757a9536117e6cdc5ba, 0x22019ad32ea3adabae68003bdefd099d7e5e3886]}
(这很好,因为 a2 中的值的数量至少为 2)
==>0x129e0131ea3cc16fe5252d7280bd1258f629f20f={a2=[0xf7958fad496d15cf9fd9e54c0012504f4fdb96ff]}
(这不好,我想 return 在我的列表中只有那些 a2 至少有 2 个值的组合)
我已经尝试在遍历本身中使用过滤器和附加的 where 步骤,但我无法做到。我不确定这是否是我应该在最后一行使用 Groovy 跳过的内容。非常感谢任何帮助或指导
最简单的方法是使用 findAll { }。
.groupBy { it.a3 }
.findAll { it.value.a2.size() > 1 }
.collectEntries { [(it.key): [a2: it.value.a2]] }
如果某些 a2 为 null,则 value.a2
也计算为 null 并过滤结果而不需要显式 nullchecks
我认为您无需进入 Groovy 即可获得所需的答案。最好在 Gremlin 中完成这一切,尤其是因为您打算过滤可能产生一些性能优势的结果。 Gremlin 有它自己的 group()
步骤以及过滤结果 Map
:
的方法
g.V().has('Transfer','eventName','Airdrop').as('t1').
out('sent_to').
dedup().as('a2').
in('sent_from').as('t2').
where('t1',eq('t2')).by('address').
out('sent_to').inV().as('a3').
select('a3','a2').
by('accountId').
group().
by('a3').
by('a2').
unfold().
where(select(values).limit(local,2).count(local).is(gte(2)))
我们的想法是使用 group()
构建您的 Map
,然后将其解构为 unfold()
的条目。您可以通过选择条目的值来使用 where()
过滤每个条目,这是 "a2" 的 List
,然后在 List
中本地计算项目。我使用 limit(local,2)
来避免超过 2 的不必要迭代,因为过滤器是 gte(2)
.
我正在进行以下遍历:
g.V().has('Transfer','eventName','Airdrop').as('t1').
outE('sent_to').
inV().dedup().as('a2').
inE('sent_from').
outV().as('t2').
where('t1',eq('t2')).by('address').
outE('sent_to').
inV().as('a3').
select('a3','a2').
by('accountId').toList().groupBy { it.a3 }.collectEntries { [(it.key): [a2 : it.value.a2]]};
正如您所看到的,我基本上是在进行遍历,最后我使用 groovy 和 collectEntries 来聚合我需要的结果,在这种情况下由 a3 聚合。结果如下所示:
==>0xfe43502662ce2adf86d9d49f25a27d65c70a709d={a2=[0x99feb505a8ed9976cf19e757a9536117e6cdc5ba, 0x22019ad32ea3adabae68003bdefd099d7e5e3886]}
(这很好,因为 a2 中的值的数量至少为 2)
==>0x129e0131ea3cc16fe5252d7280bd1258f629f20f={a2=[0xf7958fad496d15cf9fd9e54c0012504f4fdb96ff]}
(这不好,我想 return 在我的列表中只有那些 a2 至少有 2 个值的组合)
我已经尝试在遍历本身中使用过滤器和附加的 where 步骤,但我无法做到。我不确定这是否是我应该在最后一行使用 Groovy 跳过的内容。非常感谢任何帮助或指导
最简单的方法是使用 findAll { }。
.groupBy { it.a3 }
.findAll { it.value.a2.size() > 1 }
.collectEntries { [(it.key): [a2: it.value.a2]] }
如果某些 a2 为 null,则 value.a2
也计算为 null 并过滤结果而不需要显式 nullchecks
我认为您无需进入 Groovy 即可获得所需的答案。最好在 Gremlin 中完成这一切,尤其是因为您打算过滤可能产生一些性能优势的结果。 Gremlin 有它自己的 group()
步骤以及过滤结果 Map
:
g.V().has('Transfer','eventName','Airdrop').as('t1').
out('sent_to').
dedup().as('a2').
in('sent_from').as('t2').
where('t1',eq('t2')).by('address').
out('sent_to').inV().as('a3').
select('a3','a2').
by('accountId').
group().
by('a3').
by('a2').
unfold().
where(select(values).limit(local,2).count(local).is(gte(2)))
我们的想法是使用 group()
构建您的 Map
,然后将其解构为 unfold()
的条目。您可以通过选择条目的值来使用 where()
过滤每个条目,这是 "a2" 的 List
,然后在 List
中本地计算项目。我使用 limit(local,2)
来避免超过 2 的不必要迭代,因为过滤器是 gte(2)
.