You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何Gremlin查询在Gremlify与Neptune上结果不一致?

合并顶点及边属性的Gremlin查询在Gremlify与Neptune中结果不一致的原因

测试数据

g.addV("TopVertex").property('id', 4713).property('testProperty1','testProperty1').as('vertex1')
.addV("SubVertex").property('name','C1').as('C1')
.addV("SubVertex").property('name','C2').as('C2')
.addV("SubVertex").property('name','C3').as('C3')
.addE("splitsInto").from('vertex1').to('C1').property('ordinal',1)
.addE("splitsInto").from('vertex1').to('C2').property('ordinal',2)
.addE("splitsInto").from('vertex1').to('C3').property('ordinal',3)

.addV("TopVertex").property('id', 4713).property('testProperty2','testProperty2').as('vertex2')
.addV("SubVertex").property('name','C4').as('C4')
.addV("SubVertex").property('name','C5').as('C5')
.addV("SubVertex").property('name','C6').as('C6')
.addE("splitsInto").from('vertex2').to('C4').property('ordinal',4)
.addE("splitsInto").from('vertex2').to('C5').property('ordinal',5)
.addE("splitsInto").from('vertex2').to('C6').property('ordinal',6)

现有解决方案

g.addV("MergedVertex").property('id', 4713).as('mergedVertex').
V().hasLabel("TopVertex").has('id', 4713).as('oldVertices').
       outE().as('oldEdges').
       inV().as('inVertices').
       select('mergedVertex').
       addE('splitsInto').to('inVertices').as('newEdges').
       sideEffect(select('oldEdges').properties().
                  unfold().as('props').
                  select('newEdges').
                  property(select('props').key(), select('props').value())).
       select('oldVertices').drop()

问题描述

上述查询在Gremlify中执行正常,能完整复制所有边的ordinal属性;但在Neptune 1.1.1.0版本中,仅保留了两个原顶点的第一条边属性(ordinal 1和ordinal 4),其余边的属性全部丢失。

原因分析

Neptune 1.1.1.0属于较旧的引擎版本,对Gremlin遍历的作用域绑定逻辑处理与Gremlify使用的最新TinkerPop实现存在差异:

  • 原查询嵌套的sideEffect内,unfold()遍历旧边属性时,select('newEdges')没有正确关联到当前迭代生成的新边实例,而是复用了第一个创建的新边引用。
  • 这导致后续所有旧边的属性都被重复设置到第一条新边上,其余新边完全没有获得属性复制。

修复方案

方案1:直接指定属性复制(针对已知属性)

如果边属性是明确已知的(如ordinal),可以直接在创建新边时指定属性值,避免嵌套sideEffect的作用域问题:

g.addV("MergedVertex").property('id', 4713).as('mergedVertex').
V().hasLabel("TopVertex").has('id', 4713).as('oldVertices').
outE().as('oldEdges').
inV().as('inVertices').
select('mergedVertex').
addE('splitsInto').to('inVertices').
property('ordinal', select('oldEdges').values('ordinal')).
select('oldVertices').drop()

方案2:通用多属性复制(兼容任意边属性)

如果需要复制任意数量的边属性,可以调整sideEffect的嵌套结构,确保属性遍历与新边实例正确绑定:

g.addV("MergedVertex").property('id', 4713).as('mergedVertex').
V().hasLabel("TopVertex").has('id', 4713).as('oldVertices').
outE().as('oldEdges').
inV().as('inVertices').
select('mergedVertex').
addE('splitsInto').to('inVertices').as('newEdges').
sideEffect(
  select('oldEdges').properties().fold().as('edgeProps').
  select('newEdges').
  sideEffect(
    unfold('edgeProps').as('p').
    property(select('p').key(), select('p').value())
  )
).
select('oldVertices').drop()

方案3:升级Neptune引擎版本

Neptune在后续版本(如1.2.x及以上)中修复了这类Gremlin遍历作用域的兼容性问题,升级引擎版本后原查询即可正常执行。

内容的提问来源于stack exchange,提问作者r3dup

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.16 07:12:45