Gremlin中如何Upsert边并为现有属性添加新值(更新用户会话数场景)
Gremlin中如何Upsert边并为现有属性添加新值(更新用户会话数场景)
看起来你是想实现边的Upsert逻辑——如果index-1到index-2的route边存在就更新属性,不存在就创建新边,同时把现有会话数sessions加上新增的n_sessions对吧?我看了你写的Gremlin语句,主要问题出在lambda语法细节、属性名拼写,还有一些逻辑位置的调整上,我来帮你一步步修正。
先说说你遇到的报错原因
你提到的token recognition error at: '+ ',大概率是因为这几个问题:
- 代码里多了个多余的单引号:
V('index-1'')这里多打了一个单引号,属于基础语法错误 - 属性名拼写错误:你写的
edge.value('session')少了个s,应该是sessions - Lambda里的表达式没有处理空值:如果是新创建的边还没有
sessions属性,直接做加法会导致空指针,进而触发语法解析错误
修正后的完整Gremlin语句(推荐用原生步骤替代lambda,兼容性更好)
我更推荐用Gremlin原生的math步骤来实现属性累加,避免lambda在不同图数据库环境下的兼容性问题:
g.V('index-1') .outE('route') .where(inV().hasId('index-2')) .fold() .coalesce( // 如果找到边就展开 unfold(), // 如果没找到就创建新边,同时初始化max_time和sessions属性 V('index-1').addE('route').to(V('index-2')) .property('max_time', 1687219210) .property('sessions', n_sessions) ) // 只更新max_time小于目标值的边 .filter(values('max_time').is(lt(1687219211))) .property('max_time', 1687219211) // 用math步骤实现会话数累加,不用lambda更稳妥 .property('sessions', __.math('sessions + ' + n_sessions))
如果一定要用lambda的写法(Groovy环境下)
如果你是在Gremlin Console这类支持Groovy的环境下,也可以用lambda,但要修正语法和空值处理:
g.V('index-1') .outE('route') .where(inV().hasId('index-2')) .fold() .coalesce( unfold(), V('index-1').addE('route').to(V('index-2')) .property('max_time', 1687219210) .property('sessions', n_sessions) ) .filter(values('max_time').is(lt(1687219211))) .property('max_time', 1687219211) .sideEffect { edge -> // 处理sessions属性不存在的情况,默认设为0 def current = edge.value('sessions') ?: 0 edge.property('sessions', current + n_sessions) }
关键注意点
- 初始化新边的属性:创建新边时一定要给
sessions设初始值,否则累加时会因为属性不存在报错 - 优先原生步骤:lambda虽然灵活,但很多图数据库(比如Amazon Neptune)会禁用lambda,用
math这种原生步骤兼容性更强 - 语法细节检查:引号、属性名拼写这类小错误很容易触发奇怪的解析报错,写完后可以先检查一遍
备注:内容来源于stack exchange,提问作者Alexey
相关产品推荐
相关产品推荐

