我试图根据匹配每个顶点中属性的值在顶点之间创建边,将当前的隐含关系转变为显式关系。我没有成功编写一个将匹配相关顶点的小精灵遍历。
具体来说,给定下图:
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 不是创建从 Bob
到 Carol
的一条边,以及从 Dave
到 Alice
的另一条边,而是各自为所有顶点(包括他们自己)创建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('配偶')
并单独创建边?
您可以在一次遍历中实现这一点,但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()的调用是否会被任何图优化。虽然使用这种形式很简单,但是您可能会发现采用确保使用索引的方法更快,这可能意味着发出多个查询来解决问题。