如果在repeat循环之后使用,则AWS Neptune path将被截断

问题描述

g.addV('person').property('firstName','Bob').as('bob').
addV('decision').property('decision','REFER').as('brefer').select('bob').addE('hasDecision').to('brefer').
addV('phone').property('number','123').as('phone').select('bob').addE('hasPhone').to('phone').
addV('person').property('firstName','Jon').as('jon').
addV('decision').property('decision','ACCEPT').as('jaccept').select('jon').addE('hasDecision').to('jaccept').
addV('decision').property('decision','DECLINE').as('jdecline').select('jon').addE('hasDecision').to('jdecline').
addV('email').property('email','a@a.com').as('email').select('jon').addE('hasEmail').to('email').
select('jon').addE('hasPhone').to('phone').
addV('person').property('firstName','Phil').as('phil').
addV('decision').property('decision','DECLINE').as('pdecline').select('phil').addE('hasDecision').to('pdecline').
select('phil').addE('hasEmail').to('email')

在上图中,Phil通过电子邮件链接到Jon,而电子邮件又通过电话链接到Bob。每个人员节点都附加有决策节点。我需要运行一个查询,如果Phil链接到4跳内具有决策节点并附加了REFER决策的任何人,它将返回一个路径。该查询将忽略遍历中的决策节点。

答案是Phil->电子邮件(第1步)-> Jon(第2步)->电话(第3步)-> Bob(第4步)(因为Bob具有REFER决策节点)

我正在AWS Neptune上的Gremlin中编写此内容。下面的查询应返回Bob:

g.V().has('firstName','Phil').repeat(bothE().not(has(label,'hasDecision')).bothV().simplePath())
.until(out().has('decision','REFER')).path().by(valueMap()).by(label())

==>path[{firstName=[Phil]},hasEmail,{email=[a@a.com]},{firstName=[Jon]}]

它已经发现Bob-可以通过用X替换REFER来证明这一点,该返回什么都不返回-但是path()步骤只是在Jon放弃了。 看来这是一个repeat()步骤问题,可以通过简化查询来代替,直到用times()替换直到()为止。

g.V().has('firstName','hasDecision')).bothV().simplePath())
.times(2).path().by(valueMap()).by(label())
==>path[{firstName=[Phil]},{firstName=[Jon]}]

g.V().has('firstName','hasDecision')).bothV().simplePath())
.times(4).path().by(valueMap()).by(label())
==>path[{firstName=[Phil]},{firstName=[Jon]}]

请注意,最后一个查询必须在链的末尾遍历到Bob,但是path()在Jon处已放弃。

重新创建查询而没有重复给出正确的路径,但是这对我来说是不好的,因为目标节点的距离未知

 g.V().has('firstName','Phil').
bothE().not(has(label,'hasDecision')).bothV().
bothE().not(has(label,'hasDecision')).bothV().
simplePath().path().by(valueMap()).by(label())
==>path[{firstName=[Phil]},{firstName=[Jon]},hasPhone,{number=[123]},{firstName=[Bob]}]

有人看到过这种情况并且有解决方法吗?有替代path()的方法吗?该查询在Tinkergraph,BTW上运行正常(用hasLabel(...)替换has(label(...))

解决方法

事实证明,这里的解决方案很简单。遍历必须协商传入和传出的边。 E和bothV步骤均可实现此功能,但会导致遍历返回其自身。重复中的dedup(),即(bothE()... bothV()。dedup()。simplePath())确保不会发生这种情况。

g.V().has('firstName','Phil').repeat(bothE().not(has(label,'hasDecision')).bothV().dedup().simplePath()).until(out().has('decision','REFER')).path().by(valueMap()).by(label())

感谢@codetiger将我的注意力转移到边缘方向