简体   繁体   English

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

[英]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:一些解释:

  • Find A friends and store them as 'friends'.找到一个朋友并将他们存储为“朋友”。
  • Then find their friends which are within 'friends' thus friends with A (use out this time to prevent duplication).然后找到自己的朋友这是在“朋友”这样的朋友与A(使用out这个时间,以防止重复)。
  • Use project to make the result more verbose.使用 project 使结果更加冗长。
  • Selecting A, B and C to get the triad.选择 A、B 和 C 来获得三元组。

Now come the fun part of finding the triad mutual friends:现在来寻找三合会共同朋友的有趣部分:

  • Start from B and C and find their friends which are also A friends.从 B 和 C 开始,找到他们的朋友,他们也是 A 朋友。
  • Group-Count those friends and filter only those which have count of 2 (friends with both B and C).对这些朋友进行分组计数并仅过滤那些计数为 2 的朋友(同时拥有 B 和 C 的朋友)。
  • Finally, sort the results by the count of 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.

相关问题 如何使用gremlin查询将json保存为顶点属性值 - How to save json as vertex properties values using gremlin query Gremlin查询:如何在javascript中指定排序顺序 - Gremlin query: how to specify sort order in javascript (WebGL)如何将顶点添加到已初始化的顶点缓冲区? - (WebGL) How to add vertices to an already initialized vertex buffer? 根据给定的坐标,宽度和高度查找矩形顶点 - Find rectangle vertices given its coordinates, width and height 从多边形连接顶点,如何获取新多边形 - Connected vertices from polygon, how to get the new polygons 如何找到函数所属的对象? - How to find the object a function belongs to? Cayley:如何使用Cayley-Gremlin代码将顶点和边插入图形中? - Cayley: How do insert vertices and edges into graph using Cayley-Gremlin code? 如何找到给定员工代码的经理链以及如何找到给定经理代码下的所有员工 - how to find managerchain for a given employeecode and how to find all employees under the given managercode 如何查找给定字符数组中所有单词的列表 - how to find list of all words from a given array of characters 在jQuery中,如何找到与给定字符串匹配的所有元素? - In jQuery, how to find all elements matching given strings?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM