如何用gremlin在titan graph数据库中找到clique?

时间:2015-04-16 18:57:11

标签: graph neo4j titan gremlin

我需要使用cliques在我的图表中找到三个尺寸的所有Gremlin。我能够在neo4j中用cypher做到这一点:

MATCH (a)-[:edge]-(b)-[:edge]-(c)-[:edge]-(a)
RETURN a,b,c

示例情况是:A-> B-> C-> A

基于@pkohan回答的一个可能的解决方案是:

g.V().as('x').sideEffect{x = it}.out().loop(1){it.loops < 4}{if(it.loops==4){if(it.object.id==x.id){true}else{false}}else{false}}.path.dedup().collect{"${it[0].id}->${it[1].id}->${it[2].id}"}

有人有另一个想法吗?

2 个答案:

答案 0 :(得分:2)

这是一个在大型图表上效率极低的查询,但会做出您期望的结果:

g.V().filter{it.out().loop(1){it.loops < 3}.id.filter{i -> it.id == i}.hasNext()}.map

这会返回一个包含顶点的管道,这些顶点在走三条外边后可以指向自身。您可以通过更改闭包中的it.loops < 3来更改要遵循的边数。您可以通过将out()更改为in()来执行传入边缘,也可以使用both()按照任意方向操作。您还可以通过将它们放在括号中来缩小边缘类型,例如:

g.V().filter{it.out("EDGE_TYPE").loop(1){it.loops < 3}.id.filter{i -> it.id == i}.hasNext()}.map

我不确定neo4j是否具有使该查询在大型数据库上可行的优化,但我想象在具有数百万个边和顶点的titan图上运行此查询将是危险的。

答案 1 :(得分:2)

我假设您正在使用Gremlin2。

gremlin> g = TinkerGraphFactory.createTinkerGraph()
==>tinkergraph[vertices:6 edges:6]
gremlin> g.V().as('x').both().loop('x') {it.loops < 3}.both().retain('x').path()
==>[v[1], v[3], v[4], v[1]]
==>[v[1], v[4], v[3], v[1]]
==>[v[3], v[4], v[1], v[3]]
==>[v[3], v[1], v[4], v[3]]
==>[v[4], v[1], v[3], v[4]]
==>[v[4], v[3], v[1], v[4]]

正如您所看到的,它是同一个群体的6倍,只是不同的起点和终点以及不同的路径。以下是对结果集进行重复数据删除的方法:

gremlin> g.V().as('x').both().except('x').loop('x') {it.loops < 3}.both().retain('x').path().transform {it[0..2].sort()}.dedup()
==>[v[1], v[3], v[4]]

由于你要寻找的路径有一个固定的长度,你也可以摆脱循环结构(这应该会导致更快的执行):

gremlin> g.V().as('a').both().as('b').except('a').both().as('c').both().retain('a').path().transform {it[0..2].sort()}.dedup()
==>[v[1], v[3], v[4]]

您可以在Gremlin3中执行几乎相同的操作,但您也可以选择使用新的match - 步骤来查找模式(如果您知道如何编写查询,这应该非常简单CYPHER):

gremlin> graph = TinkerFactory.createModern()
==>tinkergraph[vertices:6 edges:6]
gremlin> g = graph.traversal(standard())
==>graphtraversalsource[tinkergraph[vertices:6 edges:6], standard]
gremlin> g.V().match("a",
gremlin>   __.as("a").both().as("b"),
gremlin>   __.as("b").both().as("c"),
gremlin>   __.as("c").both().as("d")).where("a", eq("d")).select("a", "b", "c").map {it.get().values().sort()}.dedup()
==>[v[1], v[3], v[4]]