gremlin 查询 n 跳并遍历所有子边和节点

问题描述 投票:0回答:1

我正在尝试创建一个图表,在其中我可以找到与给定人员的所有关系及其朋友列表。
问题陈述我的图表看起来像这样

 bob ->friends -> jay
jay -> friends -> mack 

jay -> friends - > john 
mack -> friends -> trevor

给定查询,我的原始顶点是 bob,我如何显示

的关系
bob->jay->mack
bob->jay->john

如果我进行 3 跳,它应该在结果集中包含与 mack-> trevor 的关系

这就是我所拥有的,这是我迄今为止所拥有的查询,但它只产生直接连接到 bob 的结果,并且不会在 otherV() 作为基本选择器上输出并从连接节点运行 2 跳

results = g.V().has('person', 'bob').as('node').
union(
    bothE().hasLabel('friend').as('edge').otherV().has('person').as('connectedNode'),
    both().hasLabel('friend').dedup().as('connectedNode')
).
project('node', 'edge', 'connectedNode').
   by(select('node').valueMap().unfold().dedup().fold()).
   by(select('edge').valueMap().unfold().dedup().fold()).
   by(select('connectedNode').valueMap().unfold().dedup().fold()).
toList()

获得结果的正确方法应该是什么?

gremlin tinkerpop janusgraph gremlin-server gremlinpython
1个回答
0
投票

询问有关 Gremlin 的问题时,最好包含一些示例数据作为 Gremlin 脚本:

g.addV().property('person','bob').as('bob').
  addV().property('person','jay').as('jay').
  addV().property('person','mack').as('mack').
  addV().property('person','john').as('john').
  addV().property('person','trevor').as('trevor').
  addE('friends').from('bob').to('jay').
  addE('friends').from('jay').to('mack').
  addE('friends').from('jay').to('john').
  addE('friends').from('mack').to('trevor').iterate()

我认为这个查询的基础知识最好用

path()
来完成:

gremlin> g.V().has('person','bob').out('friends').out('friends').path().by('person')
==>[bob,jay,mack]
==>[bob,jay,john]

我想你可能会遇到这样一种情况,你可能会在“朋友”边缘的任一方向上遍历,在这种情况下,你可能会想使用

simplePath()
来过滤掉循环:

gremlin> g.V().has('person','bob').both('friends').both('friends').simplePath().path().by('person')  
==>[bob,jay,mack]
==>[bob,jay,john]

也许需要考虑的一个有趣的情况是,如果您从“jay”遍历:

gremlin> g.V().has('person','jay').both('friends').both('friends').simplePath().path().by('person') 
==>[jay,mack,trevor]

在这种情况下,我们可以看到我们没有得到“[jay,john]”路径,因为从“john”开始遍历没有尚未遍历过的边,因此路径被过滤了。我们可以通过

repeat()
解决这个问题:

gremlin> g.V().has('person','jay').repeat(both('friends').simplePath()).emit(__.not(outE())).path().by('person')
==>[jay,john]
==>[jay,mack,trevor]

关键是

emit(__.not(outE()))
,其中
repeat()
只会产生没有其他边可遍历的顶点。

© www.soinside.com 2019 - 2024. All rights reserved.