如何在Gremlin / Tinkerpop中的不同顶点上执行交叉连接

时间:2017-10-26 19:21:39

标签: graph-databases gremlin titan

我是图数据库的新手。这可能是一个非常基本的问题,但任何帮助都非常感谢。 我使用Gremlin / Tinkerpop 3来查询存储在TitanDB中的图形。

以下是我的数据集。

User            |  associated_ids
---------------------------------
    A           | [ 1, 2 ]
    B           | [ 3, 4 ]
    c           | [ 5 ]
    D           | [ 4, 2 ]

现在希望获得与任何associated_id相互链接的所有用户组。 这里[A]& [D]直接相关,因为它们都有共同的实体[2]和[B]& [D]是直接相关的,因为它们都有共同的实体[4]。 所以间接[A],[B]& [D]是相互关联的。

预期结果类似。

    Users       |  associated_ids
    ----------------------------
    A,B,D       | [ 1, 2 ,3, 4]
    c           | [ 5 ]

以下是我为生成图表而执行的步骤。

    a = graph.addVertex(label, "person", "user", "A")
    b = graph.addVertex(label, "person", "user", "B")
    c = graph.addVertex(label, "person", "user", "C")
    d = graph.addVertex(label, "person", "user", "D")

    one = graph.addVertex('rec_id')
    one.property('ids', '1')

    two = graph.addVertex('rec_id')
    two.property('ids', '2')

    three = graph.addVertex('rec_id')
    three.property('ids', '3')

    four = graph.addVertex('rec_id')
    four.property('ids', '4')

    five = graph.addVertex('rec_id')
    five.property('ids', '5')

    a.addEdge('part_of',one)
    a.addEdge('part_of',two)
    b.addEdge('part_of', three)
    b.addEdge('part_of',four)
    c.addEdge('part_of',five)
    d.addEdge('part_of',four)
    d.addEdge('part_of',two)

现在想知道我如何通过任何rec_id获得彼此关联的所有用户。

获取所需输出的Gremlin查询是什么?

另外,如果我需要对图表结构进行任何更改以满足我的要求,请告诉我。

2 个答案:

答案 0 :(得分:1)

您基本上寻找的是connected components

gremlin> g.V().
           emit(cyclicPath().or().not(both())).
             repeat(both()).
             until(cyclicPath()).
           aggregate("p").by(path()).cap("p").
           unfold().limit(local, 1).dedup().
           map(__.as("v").select("p").unfold().
                  filter(unfold().where(eq("v"))).
                  unfold().dedup().order().by(id).fold()).dedup().
           project("Users","associated_ids").
             by(unfold().hasLabel("person").values("user").fold()).
             by(unfold().hasLabel("rec_id").values("ids").fold())
==>[Users:[A,B,D],associated_ids:[1,2,3,4]]
==>[Users:[C],associated_ids:[5]]

答案 1 :(得分:0)

这是获得所需答案的一种方法:

gremlin> g.V().has('rec_id','ids','1').
......1>   in().aggregate('s').
......2>   repeat(out().in().where(without('s')).aggregate('s')).
......3>   cap('s').unfold().valueMap()
==>[user:[A]]
==>[user:[D]]
==>[user:[B]]
gremlin> g.V().has('rec_id','ids','5').
......1>   in().aggregate('s').
......2>   repeat(out().in().where(without('s')).aggregate('s')).
......3>   cap('s').unfold().valueMap()
==>[user:[C]]

因此,当您遍历图表时,基本上将您的用户顶点组保存在“s”中。标有“1>”的行显示您获取所请求的“rec_id”中的初始用户的位置。在“2>”行你递归地遍历那些用户并找到他们的“rec_ids”并忽略你已经遇到过的存储在“s”中的任何用户。 “3>”的最后一行从遍历中提取“s”副作用,为方便起见,展开顶点列表并在其上运行valueMap(),以便我们很好地看到“用户”属性。