[英]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)
一些解釋:
out
這個時間,以防止重復)。現在來尋找三合會共同朋友的有趣部分:
您可以通過替換最后兩行來保留他們的數量,而不是實際的共同好友列表:
.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.