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

How to perform cross join on different vertices in Gremlin/Tinkerpop

我是图形数据库的新手。这可能是一个非常基本的问题,但非常感谢您的帮助。 我正在使用 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 查询是什么?

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

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

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() 所以我们很好地看到了 "user"属性。

您基本上要寻找的是 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]]