Gremlin中用字符串引用前置步骤时addE失败的原因排查
Gremlin查询错误原因解析
我尝试在目标顶点不存在时创建顶点和边,使用的Gremlin查询如下:
g.V(4128).as('parent').out().has('qt', 1).fold().coalesce(unfold(), addV('test').addE('test_edge').from('parent'))
但执行时抛出错误:
addE(test_edge) failed because the from() traversal (which should give
a Vertex) failed with: The provided traverser does not map to a value
我尝试了两种变体均能正常运行:
g.V(4128).as('parent').out().has('qt', 1).fold().coalesce(unfold(), addV('test')) g.V(4128).as('parent').out().has('qt', 1).fold().coalesce(unfold(), addV('test').addE('test_edge').from(__.V(4128)))
虽然我可以使用第二种变体(已知顶点ID),但希望了解原查询出错的原因。我推测是因为顶点4128没有现有边导致from('parent')失败,该错误是在清空测试图后出现的:
g.V(4128).as('parent').out() // 结果为空
错误核心原因
问题出在**as('parent')的标签作用域在fold()步骤后失效**。
fold()是Gremlin中的「屏障步骤」,它会把之前遍历产生的所有元素收集为一个集合,这个操作会重置遍历的上下文——也就是说,fold()之前通过as('parent')绑定的顶点标签,在fold()之后的coalesce分支里已经无法被访问到。
当原查询触发coalesce的第二个分支(需要创建顶点和边)时,from('parent')找不到对应的标签绑定,因此抛出「遍历器未映射到值」的错误。
你的第二个变体通过from(__.V(4128))重新查询顶点4128,绕开了标签失效的问题,所以能正常运行;第一个变体仅创建顶点,不需要引用parent标签,因此也没有问题。
优化写法(无需硬编码ID)
如果不想硬编码顶点ID,可以通过以下方式保留parent的上下文:
// 方式1:用select('parent')将顶点上下文带入coalesce分支 g.V(4128).as('parent').out().has('qt', 1).fold().coalesce(unfold(), select('parent').addV('test').addE('test_edge').from('parent'))
// 方式2:用project保留parent和children的信息 g.V(4128).as('parent').project('parent', 'children').by(identity()).by(out().has('qt', 1).fold()).coalesce(select('children').unfold(), select('parent').addV('test').addE('test_edge').from('parent'))
内容的提问来源于stack exchange,提问作者gph
相关产品推荐
相关产品推荐

