在 Gremlin 中相互提及的用户

Users who mentioned each other in Gremlin

我们有一个较小的 Twitter 数据库示例:

user -[TWEETED]-> tweet -[MENTIONED]-> user2

我想了解如何在 Gremlin 中编写查询,以显示谁是相互提及的用户。我已经阅读了文档,但我不知道该怎么做。

鉴于此样本数据假设 marko 和 stephen 相互提及并且 marko 和 daniel 相互提及:

g = new TinkerGraph()
vMarko = g.addVertex("marko", [type:"user"])
vStephen = g.addVertex("stephen", [type:"user"])
vDaniel = g.addVertex("daniel", [type:"user"])
vTweetm1s = g.addVertex("m1s", [type:"tweet"])
vTweetm2d = g.addVertex("m2d", [type:"tweet"])
vTweets1m = g.addVertex("s1m", [type:"tweet"])
vTweetd1m = g.addVertex("d1m", [type:"tweet"])

vMarko.addEdge("tweeted",vTweetm1s)
vMarko.addEdge("tweeted",vTweetm2d)
vStephen.addEdge("tweeted",vTweets1m)
vDaniel.addEdge("tweeted",vTweetd1m)
vTweetm1s.addEdge("mentioned", vStephen)
vTweetm2d.addEdge("mentioned", vDaniel)
vTweets1m.addEdge("mentioned", vMarko)
vTweetd1m.addEdge("mentioned", vMarko)

您可以通过以下方式处理它:

gremlin> g.V.has("type","user").as('s')
            .out("tweeted").out("mentioned").as('m').out("tweeted")
            .out("mentioned").as('e').select.filter{it[0]==it[2]}       
==>[s:v[daniel], m:v[marko], e:v[daniel]]
==>[s:v[stephen], m:v[marko], e:v[stephen]]
==>[s:v[marko], m:v[stephen], e:v[marko]]
==>[s:v[marko], m:v[daniel], e:v[marko]]

此方法使用 select 从标记的步骤中提取数据,然后使用最终的 filter 找到 "s"(第一个位置的顶点)等于 "e"(顶点在最终位置)。这当然意味着检测到循环模式,其中一个用户提到了另一个用户,而另一个用户在某个时候又提到了那个人。

如果你遵循那么多,那么我们可以稍微清理一下结果以获得唯一的一对:

gremlin> g.V.has("type","user").as('s')
            .out("tweeted").out("mentioned").as('m')
            .out("tweeted").out("mentioned").as('e')
            .select.filter{it[0]==it[2]}
            .transform{[it[0].id,it[1].id] as Set}.toList() as Set
==>[daniel, marko]
==>[stephen, marko]

通过在前面的代码中加入一个transform,我们可以将结果转换为"id"(本例中的用户名)并将所有内容翻转为Set,从而得到独特的结果对。