提问者:小点点

通过属性匹配遍历隐含边缘?


我试图根据匹配每个顶点中属性的值在顶点之间创建边,将当前的隐含关系转变为显式关系。我没有成功编写一个将匹配相关顶点的小精灵遍历。

具体来说,给定下图:

g = TinkerGraph.open().traversal()
g.addV('person').property('name','alice')
g.addV('person').property('name','bob').property('spouse','carol')
g.addV('person').property('name','carol')
g.addV('person').property('name','dave').property('spouse', 'alice')

我希望我可以使用以下内容创建一个spouse_of关系

> g.V().has('spouse').as('x')
   .V().has('name', select('x').by('spouse'))
       .addE('spouse_of').from('x')

但是,Bob 和 Dave 不是创建从 BobCarol 的一条边,以及从 DaveAlice 的另一条边,而是各自为所有顶点(包括他们自己)创建spouse_of条边:

> g.V().out('spouse_of').path().by('name')
  ==>[bob,alice]
  ==>[bob,bob]
  ==>[bob,carol]
  ==>[bob,dave]
  ==>[dave,carol]
  ==>[dave,dave]
  ==>[dave,alice]
  ==>[dave,bob]

似乎<code>has</code>过滤器没有被应用,或者,使用RDBMS术语,好像我最终得到了一个“外部连接”而不是我想要的“内部连接”。

有什么建议吗?我是否忽略了一些琐碎或深刻的东西(也许是本地与全局范围)?有没有什么方法可以在单个遍历查询中实现这一点,或者我必须遍历g.has('配偶')并单独创建边?


共1个答案

匿名用户

您可以在一次遍历中实现这一点,但has()并不意味着这样做。Gremlin Recipes教程的traversal Induced Values部分描述了这种遍历类型的模式,但您可以在这里看到它的实际操作:

gremlin> g.V().hasLabel('person').has('spouse').as('s').
......1>   V().hasLabel('person').as('x').
......2>   where('x', eq('s')).
......3>     by('name').
......4>     by('spouse').
......5>   addE('spouse_of').from('s').to('x')
==>e[10][2-spouse_of->5]
==>e[11][7-spouse_of->0]
gremlin> g.E().project('x','y').by(outV().values('name')).by(inV().values('name'))
==>[x:bob,y:carol]
==>[x:dave,y:alice]

虽然这可以在一次遍历中完成,但请注意,根据数据的大小,这可能是一次开销很大的遍历,因为我不确定对< code>V()的调用是否会被任何图优化。虽然使用这种形式很简单,但是您可能会发现采用确保使用索引的方法更快,这可能意味着发出多个查询来解决问题。