我正在尝试检索一些身份顶点和他们所属的任何组。图形结构看起来像这样。请注意,该组织有多个用户,我试图选择所有这些用户,并且这些用户中的每一个都可以属于多个组。(本质上,这是标准的用户帐户和组的安排。)
alice = g.addV('Identity').property('email', 'alice@example.test').next()
alfred = g.addV('Identity').property('email', 'alfred@example.test').next()
org = g.addV('Organization').property('name', 'Example Inc').next()
[alice, alfred].each { g.V(org).addE('user').to(it).iterate() }
a = g.addV('Group').property('name', 'starts with A').next()
f = g.addV('Group').property('name', 'five letters').next()
[a, f].each { g.V(it).addE('member').to(alice).iterate() }
g.V(A).addE('member').to(alfred).iterate()
我的遍历的主要逻辑按预期工作:
gts.V(organization)
.out(ORG_USERS).as('i')
.in(GROUP_USERS)
.valueMap('name').with(tokens)
.as('g')
.select('i', 'g')
.by(__.valueMap('email').with(tokens))
.toList()
但是,这会生成一个包含键 i
和 g
的映射列表,特别是如果标识在多个组中,则会复制标识。相反,我想折叠组。我尝试过这样做(还没有尝试删除实际的组结果,只是按身份对它们进行分组):
gts.V(organization)
.out(ORG_USERS).as('i')
.in(GROUP_USERS)
.valueMap('name').with(tokens)
.fold()
.as('gs')
.select('i', 'gs')
.by(__.valueMap('email').with(tokens))
.toList()
但是,即使fol()
接收到带有传入Group-as-map的遍历器,并且简单地返回fol()
的结果会产生预期的嵌套列表,select('i','gs')
返回零结果。(我可以select('gs')
,但select('i')
和select('i','gs')
都是空的。)
我应该如何构建遍历,以便获得所需的元组(标识,列表[组])?
使用您的示例数据,我更改了查询,例如,使用< code>project步骤。如果这不是你想要的,我们可以重复一点。
gremlin> g.V(org).
......1> project('i','g').
......2> by(out().valueMap().fold()).
......3> by(out().in().valueMap().fold())
==>[i:[[email:[alice@example.test]]],g:[[name:[starts with A]],[name:[five letters]],[name:[Example Inc]]]]
如果您需要将< code>project步骤应用于组织的扇出,可以使用
gremlin> g.V(org).
......1> out().
......2> project('i','g').
......3> by(valueMap().fold()).
......4> by(__.in().valueMap().fold())
==>[i:[[email:[alice@example.test]]],g:[[name:[starts with A]],[name:[five letters]],[name:[Example Inc]]]]
根据下面的讨论进行了更新。使用组
步骤将生成从电子邮件到它们拥有的连接的分组。
gremlin> g.V(org).
......1> out().
......2> group().
......3> by(values('email')).
......4> by(__.in().values('name').fold()).
......5> unfold()
==>alfred@example.test=[starts with A, Example Inc]
==>alice@example.test=[starts with A, five letters, Example Inc]