【问题标题】:How do I fold a list of related vertices with the primary vertex?如何折叠与主顶点相关的顶点列表?
【发布时间】:2021-05-31 10:17:20
【问题描述】:

我正在尝试检索一些身份顶点以及它们所属的任何组。图结构看起来像这样。请注意,组织有多个用户,我试图选择所有这些用户,并且每个用户都可以在多个组中。 (这本质上是标准的用户-帐户-组安排。)

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

然而,这会产生一个带有键 ig 的映射列表,特别是如果它位于多个组中,则会复制一个身份。相反,我想折叠组。我试过这样(还没有尝试对实际的组结果进行重复数据删除,只是按身份对它们进行分组):

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

然而,即使 fold() 接收到带有传入 Group-as-map 的遍历器,并且简单地返回 fold() 的结果会产生预期的嵌套列表,select('i', 'gs') 也会返回零结果。 (我可以select('gs'),但select('i')select('i', 'gs') 都是空的。)

我应该如何构造一个遍历,以便获得所需的 (Identity, List[Group]) 元组?

【问题讨论】:

  • fold 步骤之后,之前的标签如i 将丢失。您应该能够只重写一点并使用project。如果您可以添加一些基本的addEaddV 步骤来构建示例图,从而更轻松地测试答案。
  • @KelvinLawrence 添加。在实际代码中,还有一个“组由组织定义”的反向引用;如果它会产生重大影响,我将对其进行编辑以包含它,但这似乎只是在in(GROUP_USERS) 之后挂一个.where(...)

标签: java groovy gremlin tinkerpop3


【解决方案1】:

使用您的示例数据,我更改了查询,例如,使用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]]]] 

如果您需要 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]]]] 

根据下面的讨论更新。使用group 步骤会产生从电子邮件到他们拥有的连接的分组。

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]  

【讨论】:

  • 这似乎收集了所有i 和所有g,但两者之间没有任何关联(即,哪些用户与哪些组相关联)。
  • 在示例图中,Alice 连接到所有这些组。你能显示你想看到的输出吗? gremlin> g.V(org).out().in().path().by(valueMap()) ==>[[name:[Example Inc]],[email:[alice@example.test]],[name:[starts with A]]] ==>[[name:[Example Inc]],[email:[alice@example.test]],[name:[five letters]]] ==>[[name:[Example Inc]],[email:[alice@example.test]],[name:[Example Inc]]]
  • 我将扩展我的示例;情况是每个原点可以有很多i,我需要知道身份列表和它们所在的组。
  • 此外,如果我还需要说/*group*/.where(__in('definedBy').is('org')project 是否会起作用,例如project('gs').by(__.in('member').where(__.in('definedBy').is('org')))(即,“该用户是成员的组并且该组由原来的组织”)?
  • 我会尝试更新答案(尽快)。不过,将project 替换为group 可能就是您在这里需要做的所有事情。按所有 i 及其传入顶点分组。
猜你喜欢
  • 1970-01-01
  • 2019-01-03
  • 1970-01-01
  • 1970-01-01
  • 2020-07-30
  • 2017-05-07
  • 1970-01-01
  • 2010-12-26
  • 2018-03-22
相关资源
最近更新 更多