繁体   English   中英

在gremlin中,如何查找和排序给定顶点所属的所有连接顶点的三元组?

[英]In gremlin, how to find and sort all triads of connected vertices that a given vertex belongs to?

我正在制作一个社交应用程序,用户可以在其中成为朋友。

对于给定的用户A ,我想找到所有用户三合会,例如A -isFriends-> B AND B -isFriends-> C AND C -isFriends-> A

我目前的做法如下:

g.V(A).repeat(__.out('isFriends')).times(3).path().by(id).toList()

然后在 gremlin 之外,我过滤掉第一个对象与最后一个对象不同的所有 Path 对象。 我更愿意让 gremlin 为我做这个过滤,但我不确定如何根据path()的输出进行过滤。

我尝试过cyclicPath() ,但这只是返回一个我不明白的 Vertex 对象的平面列表。 由此我期望与path()类似的输出,但只包含第一个和最后一个顶点相同的路径。 让我知道这种期望是否不正确。

我还想根据子遍历的结果(三个顶点有多少共同朋友)对这些路径进行排序,但我不确定如何从包含在path()输出中的顶点开始遍历,无需启动新的 gremlin 查询。

我正在使用 javascript-gremlin 驱动程序 (v3.4.4) 并且正在对 AWS Neptune 进行查询,其中 lambdas 不可用。

如果我的方法或理解不正确,请告诉我。

所以我尝试为您的问题创建一个示例图:示例图

您正在尝试找到一条简单的循环路径,我认为您可以通过以下方式实现:

g.V().hasLabel('A').as('a')
.both('isFriends').as('b')
.both('isFriends').as('c')
.where(both('isFriends').hasLabel('A'))
.select('a', 'b', 'c')

注意:黑社会是对称的,所以他们每个人都会返回两次。

下面是一个查询来回答你的两个问题。 它已优化为仅运行 2 跳:

g.V().hasLabel("A").as("A").both("isFriends").as("B").aggregate("friends")
.out("isFriends").as("C").where(within("friends"))
.project("triad","mutual")
  .by(select("A","B","C").by(label()))
  .by(select("B","C").select(values).unfold()
    .both("isFriends").where(within("friends"))
    .groupCount().by().unfold()
    .where(select(values).is(eq(2)))
    .select(keys).label().fold())
.order().by(select("mutual").count(local), desc)

一些解释:

  • 找到一个朋友并将他们存储为“朋友”。
  • 然后找到自己的朋友这是在“朋友”这样的朋友与A(使用out这个时间,以防止重复)。
  • 使用 project 使结果更加冗长。
  • 选择 A、B 和 C 来获得三元组。

现在来寻找三合会共同朋友的有趣部分:

  • 从 B 和 C 开始,找到他们的朋友,他们也是 A 朋友。
  • 对这些朋友进行分组计数并仅过滤那些计数为 2 的朋友(同时拥有 B 和 C 的朋友)。
  • 最后,按共同朋友的数量对结果进行排序。

您可以通过替换最后两行来保留他们的数量,而不是实际的共同好友列表:

    .select(keys).label().fold())
.order().by(select("mutual").count(local), desc)

和:

    .count())
.order().by(select("mutual"), desc)

最后,如果您只想要黑社会(仍然排序),您可以删除项目:

g.V().hasLabel("A").as("A").both("isFriends").as("B").aggregate("friends")
.out("isFriends").as("C").where(within("friends"))
.order().by(
    select("B","C").select(values).unfold()
    .both("isFriends").where(within("friends"))
    .groupCount().by().unfold().where(select(values).is(eq(2)))    
    .count(), desc)
.select("A","B","C").by(label()).select(values)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM