簡體   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