问题描述
我编写了一个脚本来避免为顶点和边创建重复项,但是我在处理边时遇到了一些麻烦。 这是脚本:
g.V().has('dog','name','pluto').fold().\
coalesce(__.unfold(),__.addV('dog').property('name','pluto')).store('dog').\
V().has('person','sam').fold().\
coalesce(__.unfold(),__.addV('person').property('name','sam')).store('person').\
select('person').unfold().\
coalesce(__.outE('has_dog').where(__.inV().has(T.id,__.select('dog').unfold().id())),__.addE('has_dog').to(__.select('person').unfold())).toList()
通过这个,我创建了新的两个顶点和新边。如果我再次执行它,则不会创建新的顶点和边。目前一切正常。
如果我用 'charlie' 改变 'pluto' 来创建一个新的 'dog' 顶点,这个脚本会创建新的顶点但返回用 'pluto' 创建的前一个边。因此,如果该“人”已经拥有这种关系,则脚本不会创建新的关系。
我不明白的是代码
__.select('dog').unfold().id()
应该返回新/旧 'dog' 顶点的 id 并检查带有 'person' 的边是否存在。 例如,如果我执行该脚本以获取 id 并用该 id 替换该脚本,例如
__.outE('has_dog').where(__.inV().has(T.id,42))
脚本正常工作并使用新的“狗”顶点创建边。
为什么使用脚本获取 id 不起作用,但使用整数却有效?没有意义,因为我应该有相同的结果。
谢谢。
解决方法
您遇到的问题是 has
步不能进行任意遍历,但 where
步可以。您只需要将 has
步骤重新表述为 where
步骤。如果 has
步骤中的任意遍历返回任何结果,则将其视为“真”。这是 Gremlin 的事情之一,它看起来应该可以工作,但实际上却没有。
这是一个人为的例子,展示了对您的情况应该有帮助的 where...by
模式。
gremlin> g.V(3).as('x').V().where(eq('x')).by(id)
==>v[3]
当您使用 store
时,where
步骤变成这样
gremlin> g.V(3).store('x').V().where(eq('x')).by(id).by(unfold().id())
==>v[3]
所以你的代码中的行最终会是这样的
filter(__.inV().where(eq('dog')).by(T.id).by(unfold().id()))