[英]In gremlin, how to find and sort all triads of connected vertices that a given vertex belongs to?
I am making a social app where users can be friends.我正在制作一个社交应用程序,用户可以在其中成为朋友。
For a given user A
, I want to find all of the triads of users such that A -isFriends-> B AND B -isFriends-> C AND C -isFriends-> A
.对于给定的用户A
,我想找到所有用户三合会,例如A -isFriends-> B AND B -isFriends-> C AND C -isFriends-> A
。
My current approach is as follows:我目前的做法如下:
g.V(A).repeat(__.out('isFriends')).times(3).path().by(id).toList()
and then outside of gremlin, I filter out all of the Path objects where the first object is not the same as the last object.然后在 gremlin 之外,我过滤掉第一个对象与最后一个对象不同的所有 Path 对象。 I'd prefer to have gremlin do this filtering for me, but I'm unsure how to filter based on the output of path()
.我更愿意让 gremlin 为我做这个过滤,但我不确定如何根据path()
的输出进行过滤。
I have tried cyclicPath()
, but this simply returns a flat list of Vertex objects, which I do not understand.我尝试过cyclicPath()
,但这只是返回一个我不明白的 Vertex 对象的平面列表。 From this I would expect similar output to path()
but with only the paths where the first and last vertices are the same included.由此我期望与path()
类似的输出,但只包含第一个和最后一个顶点相同的路径。 Let me know if this expectation is incorrect.让我知道这种期望是否不正确。
I would also like to then sort these paths based on the results of a sub-traversal (how many mutual friends the three vertices have), but I am unsure how to run a traversal starting on the vertices included in the output of path()
, without starting a new gremlin query.我还想根据子遍历的结果(三个顶点有多少共同朋友)对这些路径进行排序,但我不确定如何从包含在path()
输出中的顶点开始遍历,无需启动新的 gremlin 查询。
I am using the javascript-gremlin driver (v3.4.4) and am making queries against AWS Neptune, where lambdas are not available.我正在使用 javascript-gremlin 驱动程序 (v3.4.4) 并且正在对 AWS Neptune 进行查询,其中 lambdas 不可用。
Please let me know if my approach or understanding is off.如果我的方法或理解不正确,请告诉我。
So I tried to create a sample graph for your issue: sample graph所以我尝试为您的问题创建一个示例图:示例图
You are trying to find a simple cyclic path I think you can achieve that with:您正在尝试找到一条简单的循环路径,我认为您可以通过以下方式实现:
g.V().hasLabel('A').as('a')
.both('isFriends').as('b')
.both('isFriends').as('c')
.where(both('isFriends').hasLabel('A'))
.select('a', 'b', 'c')
Note: that triads are symmetric so each of them will return twice.注意:黑社会是对称的,所以他们每个人都会返回两次。
Below is a query to answer both your questions.下面是一个查询来回答你的两个问题。 It is optimized to run with only 2 hops:它已优化为仅运行 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)
Some explanation:一些解释:
out
this time to prevent duplication).然后找到自己的朋友这是在“朋友”这样的朋友与A(使用out
这个时间,以防止重复)。Now come the fun part of finding the triad mutual friends:现在来寻找三合会共同朋友的有趣部分:
Instead of actual list of mutual friends, you can keep only their count by replacing last 2 lines:您可以通过替换最后两行来保留他们的数量,而不是实际的共同好友列表:
.select(keys).label().fold())
.order().by(select("mutual").count(local), desc)
with:和:
.count())
.order().by(select("mutual"), desc)
Finally, if you want only the triads (still sorted) you can remove the project:最后,如果您只想要黑社会(仍然排序),您可以删除项目:
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.