Gremlin:确定另一个顶点的所有连接中的顶点

时间:2018-02-04 04:40:37

标签: graph-databases gremlin tinkerpop tinkerpop3

我正在使用TinkerPop3 Gremlin Console 3.3.1来分析图形数据库。我想确定哪些顶点的连接与同一标签的其他顶点的所有相似连接重叠。例如,为了清晰起见,使用带有附加“软件”顶点的TinkerFactory Modern图形和两个“创建”边缘:

graph = TinkerFactory.createModern()
==>tinkergraph[vertices:6 edges:6]
g = graph.traversal() 
==>graphtraversalsource[tinkergraph[vertices:6 edges:6], standard]
graph.addVertex(T.label, "software", T.id, 13, "name", “sw")
==>v[13]
g.V("4").addE("created").to(V("13"))
==>e[14][4-created->13]
g.V("6").addE("created").to(V("5"))
==>e[15][6-created->5]

请参阅我修改的现代图形的以下图像。我把我感兴趣的箭头用橙色。

Modified TinkerFactory Modern graph visual

通过这个例子,我想确定哪些人创建的软件包含了另一个人创建的所有软件。没有必要知道哪个软件。所以这个例子的结果将是:

  • Josh(V(4))共同创建了由Marko(V(1))创建的所有软件
  • Josh(V(4))共同创建了Peter(V(6))
  • 创建的所有软件
  • Peter(V(6))共同创建了由Marko(V(1))
  • 创建的所有软件

另一种说法是“Marko创作的所有软件也让Josh成为创作者”,等等。

以下代码是我能得到的。这意味着通过检查每个人和“a”之间共享的软件数量是否等于“a”创建的软件总量来找到重叠连接。不幸的是,它没有给出结果。

gremlin> 
g.V().has(label,"person").as("a").
    both().has(label,"software").aggregate("swA").
    both().has(label,"person").where(neq("a")).dedup().
    where(both().has(label,"software").
       where(within("swA")).count().
           where(is(eq(select("swA").unfold().count())
           )
        )
    ).as("b").select("a","b").by(“name”)

非常感谢任何帮助!

1 个答案:

答案 0 :(得分:3)

首先找到共同创建至少一种产品的所有人。

g.V().hasLabel('person').as('p1').
  out('created').in('created').
  where(neq('p1')).as('p2').
  dedup('p1','p2').
  select('p1','p2').
    by('name')

从那里,您可以添加一些模式匹配,以验证人p1的已创建产品的数量是否与这些产品与人p2的连接数相匹配。

g.V().hasLabel('person').as('p1').
  out('created').in('created').
  where(neq('p1')).as('p2').
  dedup('p1','p2').
  match(__.as('p1').out('created').fold().as('x'),
        __.as('x').count(local).as('c'),
        __.as('x').unfold().in('created').where(eq('p2')).count().as('c')).
  select('p1','p2').
    by('name')

结果:

gremlin> g.V().hasLabel('person').as('p1').
......1>   out('created').in('created').
......2>   where(neq('p1')).as('p2').
......3>   dedup('p1','p2').
......4>   match(__.as('p1').out('created').fold().as('x'),
......5>         __.as('x').count(local).as('c'),
......6>         __.as('x').unfold().in('created').where(eq('p2')).count().as('c')).
......7>   select('p1','p2').
......8>     by('name')
==>[p1:marko,p2:josh]
==>[p1:marko,p2:peter]
==>[p1:peter,p2:josh]