精怪查询基于边缘性递归获取节点

问题描述:

考虑下面的示例数据,我想建立一个小鬼查询返回的红宝石连接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相当陌生,我一直在困惑的几个食谱有我的理想查询共同的东西,但我仍然看不到如何到达那里...

非常感谢您提供的任何帮助或建议。

当问小鬼问题,它总是帮助那些试图回答,如果你提供可以轻松剪切和粘贴到小鬼控制台这样的样品图:

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。 –