我正在制作一款社交应用,用户可以在其中成为 friend 。
对于给定用户A
,我想找到所有满足以下条件的用户三元组:A -isFriends-> B AND B -isFriends-> C AND C -isFriends->一个
。
我目前的做法如下:
g.V(A).repeat(__.out('isFriends')).times(3).path().by(id).toList()
然后在 gremlin 之外,我过滤掉第一个对象与最后一个对象不同的所有 Path 对象。我更愿意让 gremlin 为我执行此过滤,但我不确定如何根据 path()
的输出进行过滤。
我尝试过cycloPath()
,但这只是返回一个 Vertex 对象的平面列表,我不明白。由此,我期望与 path()
类似的输出,但仅包含第一个和最后一个顶点相同的路径。如果这个期望不正确,请告诉我。
我还想根据子遍历的结果(三个顶点有多少个共同的 friend )对这些路径进行排序,但我不确定如何从输出中包含的顶点开始运行遍历path()
,无需启动新的 gremlin 查询。
我正在使用 javascript-gremlin 驱动程序 (v3.4.4),并且正在针对 AWS Neptune 进行查询,其中 lambda 不可用。
如果我的方法或理解有问题,请告诉我。
最佳答案
下面是回答您两个问题的查询。它优化只需要 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 好友并将他们存储为“好友”。
- 然后找到他们在“ friend ”中的 friend ,即与 A 的 friend (这次使用
out
来防止重复)。 - 使用项目使结果更加详细。
- 选择 A、B 和 C 即可获得三元组。
现在来了寻找三合会共同 friend 的有趣部分:
- 从B和C开始,找到他们的 friend ,也是A friend 。
- 对这些好友进行分组计数,并仅过滤那些计数为 2 的好友(同时具有 B 和 C 的好友)。
- 最后,按照共同好友的数量对结果进行排序。
您可以通过替换最后两行来仅保留他们的计数,而不是实际的共同 friend 列表:
.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)
关于javascript - 在 gremlin 中,如何查找和排序给定顶点所属的所有连通顶点三元组?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60156915/