2017-07-16 98 views
0

考慮下面的示例數據,我想建立一個小鬼查詢返回的紅寶石連接Alice的網絡,3級深:精怪查詢基於邊緣性遞歸獲取節點

Vertex: Alice 
Vertex: Bobby 
Vertex: Cindy 
Vertex: David 
Vertex: Eliza 

Edge: [Alice] -> [Rates(tag:ruby,value:0.9)] -> [Bobby] 
Edge: [Bobby] -> [Rates(tag:ruby,value:0.8)] -> [Cindy] 
Edge: [Cindy] -> [Rates(tag:ruby,value:0.7)] -> [David] 
Edge: [David] -> [Rates(tag:ruby,value:0.6)] -> [Eliza] # ignored, level 4 
Edge: [Alice] -> [Rates(tag:java,value:0.9)] -> [Eliza] # ignored, not ruby 

所以返回數據應該類似於:

Bobby: [0.9] 
Cindy: [0.9, 0.8] 
David: [0.9, 0.8, 0.7] 

其中返回每個頂點ID以及評估值的路徑數組。

我在JanusGraph(Gremlin 3)的當前版本中工作。我對Gremlin相當陌生,我一直在困惑的幾個食譜有我的理想查詢共同的東西,但我仍然看不到如何到達那裏...

非常感謝您提供的任何幫助或建議。

回答

2

當問小鬼問題,它總是幫助那些試圖回答,如果你提供可以輕鬆剪切和粘貼到小鬼控制檯這樣的樣品圖:

graph = TinkerGraph.open() 
g = graph.traversal() 
g.addV().property('name','alice').as('a'). 
    addV().property('name','bobby').as('b'). 
    addV().property('name','cindy').as('c'). 
    addV().property('name','david').as('d'). 
    addV().property('name','eliza').as('e'). 
    addE('rates').property('tag','ruby').property('value',0.9).from('a').to('b'). 
    addE('rates').property('tag','ruby').property('value',0.8).from('b').to('c'). 
    addE('rates').property('tag','ruby').property('value',0.7).from('c').to('d'). 
    addE('rates').property('tag','ruby').property('value',0.6).from('d').to('e'). 
    addE('rates').property('tag','java').property('value',0.9).from('a').to('e').iterate() 

使用這個圖表我想出了這種方法得到的結果,你的願望:

gremlin> g.V().has('name','alice'). 
......1> repeat(outE().has('tag','ruby').inV()). 
......2>  times(3). 
......3>  emit(). 
......4> group(). 
......5>  by('name'). 
......6>  by(path(). 
......7>  unfold(). 
......8>  has('value'). 
......9>  values('value'). 
.....10>  fold()) 
==>[bobby:[0.9],cindy:[0.9,0.8],david:[0.9,0.8,0.7]] 

emit()隨訪至3線可能是不言自明 - 找到「愛麗絲」然後遍歷out()反覆深度爲3,放出沿途發現每個頂點。這讓你你關心的頂點:

gremlin> g.V().has('name','alice'). 
......1> repeat(outE().has('tag','ruby').inV()). 
......2>  times(3). 
......3>  emit() 
==>v[2] 
==>v[4] 
==>v[6] 

更復雜的部分談到在這之後,你所關心的檢索路徑信息,每個這樣就可以沿着每個「速度」搶「值」屬性邊緣。我選擇使用group,這樣我就可以很容易地得到您想要的Map結構。很顯然,如果「bobby」在樹上出現過兩次,那麼他的Map條目最終會有兩個評級列表。

如果您挑選group()中發生的事情,您可以看到它被兩個by()選項調製。第一個對應於Map中的鍵(顯然,我假設「名稱」是唯一的)。第二個提取當前移動器(人頂點)的路徑。在進一步討論之前先看看輸出會變成什麼樣子只是path()

gremlin> g.V().has('name','alice'). 
......1> repeat(outE().has('tag','ruby').inV()). 
......2>  times(3). 
......3>  emit(). 
......4> group(). 
......5>  by('name'). 
......6>  by(path()).next() 
==>bobby=[v[0], e[10][0-rates->2], v[2]] 
==>cindy=[v[0], e[10][0-rates->2], v[2], e[11][2-rates->4], v[4]] 
==>david=[v[0], e[10][0-rates->2], v[2], e[11][2-rates->4], v[4], e[12][4-rates->6], v[6]] 

下面的步驟操作path()這條道路進入你想要的形式。它展開每條路徑,然後通過查找「value」的邊緣唯一屬性過濾掉邊緣,然後提取該屬性,然後將值摺疊回地圖中每個值的列表。

+0

謝謝Stephen!偉大的解決方案,以及很好的解釋。 +100。 –