Gremlin/Tinkerpop3中如何查询多个顶点及其关系的个数?

How to query for multiple vertices and counts of their relationships in Gremlin/Tinkerpop 3?

我正在使用 Gremlin/Tinkerpop 3 查询存储在 TitanDB 中的图形。

该图包含具有属性的用户顶点,例如 "description",以及表示用户之间关系的边。

我想使用 Gremlin 来获取 1) 按属性的用户和 2) 与其他用户(例如,id = 123)的关系(在这种情况下是任何类型)的数量。为了实现这一点,我在 Gremlin 3 中使用 match 操作,如下所示:

g.V().match('user',__.as('user').has('description',new P(CONTAINS,'developer')),
__.as('user').out().hasId(123).values('name').groupCount('a').cap('a').as('relationships'))
.select()

这个查询工作正常,除非有多个用户顶点返回,例如,因为多个用户在他们的描述中有单词 "developer"。在这种情况下,关系中的计数是所有返回用户与 ID 为 123 的用户之间所有关系的总和,而不是根据需要,每个返回用户的个人计数。

我是不是做错了什么或者这可能是一个错误?

PS:这个问题与我前段时间发布的关于 Tinkerpop 2 中类似查询的问题有关,我在那里遇到了另一个问题:How to select optional graph structures with Gremlin?

这是我使用的示例数据:

graph = TinkerGraph.open()
g = graph.traversal()
v123=graph.addVertex(id,123,"description","developer","name","bob")
v124=graph.addVertex(id,124,"description","developer","name","bill")
v125=graph.addVertex(id,125,"description","developer","name","brandy")
v126=graph.addVertex(id,126,"description","developer","name","beatrice")
v124.addEdge('follows',v125)
v124.addEdge('follows',v123)
v124.addEdge('likes',v126)
v125.addEdge('follows',v123)
v125.addEdge('likes',v123)
v126.addEdge('follows',v123)
v126.addEdge('follows',v124)

我的第一个想法是:"Do we really need match step"?其次,当然,我想用 TP3 的方式写这个,而不是使用 lambda/closure。我在第一次迭代中尝试了各种方法,最接近的是来自 Daniel Kuppitz 的这样的东西:

gremlin> g.V().as('user').local(out().hasId(123).values('name')
              .groupCount()).as('relationships').select()
==>[relationships:[:]]
==>[relationships:[bob:1]]
==>[relationships:[bob:2]]
==>[relationships:[bob:1]]

所以这里我们使用了local步来限制local内的遍历到当前元素。这行得通,但是我们在 select 中丢失了 "user" 标签。为什么? groupCountReducingBarrierStep 并且路径在这些步骤之后丢失。

好吧,让我们回到match。我想我可以尝试使用 local:

进行 match 步遍历
gremlin> g.V().match('user',__.as('user').has('description','developer'),
gremlin>             __.as('user').local(out().hasId(123).values('name').groupCount()).as('relationships')).select()
==>[relationships:[:], user:v[123]]
==>[relationships:[bob:1], user:v[124]]
==>[relationships:[bob:2], user:v[125]]
==>[relationships:[bob:1], user:v[126]]

好的 - 成功 - 这就是我们想要的:没有 lambda 和本地计数。但是,它仍然让我感觉:"Do we really need match step"?就在那时,Kuppitz 先生得出了最终答案,该答案大量使用了 by 步骤:

gremlin> g.V().has('description','developer').as("user","relationships").select().by()
              .by(out().hasId(123).values("name").groupCount())
==>[user:v[123], relationships:[:]]
==>[user:v[124], relationships:[bob:1]]
==>[user:v[125], relationships:[bob:2]]
==>[user:v[126], relationships:[bob:1]]

如您所见,by 可以链接(在某些步骤上)。第一个 by 按顶点分组,第二个 by 使用 "local" groupCount 处理分组的元素。