JanusGraph遍历求助:按强度遍历至叶子节点的查询失效问题
修复JanusGraph Gremlin遍历查询问题
原查询的核心问题
- 未按边强度排序:原查询中
outE("ML_EDGE").limit(1)没有按STRENGTH降序排序,无法保证每次选取的是强度最高的边。 - 叶子节点判断逻辑错误:原查询用
outE().count().is(eq(0))判断叶子节点,这会忽略顶点存在其他类型边或STRENGTH≤0的ML_EDGE的情况,应该判断是否存在符合条件的边(即ML_EDGE且STRENGTH>0)。 - 遍历中断导致空结果:当顶点没有符合条件的边时,
repeat中的outE步骤返回空,整个遍历器无输出,最终返回空结果。
修复后的查询
方案1:返回最终到达的顶点(优先推荐)
g.V().has('ID','id') .repeat( outE("ML_EDGE").has("STRENGTH", gt(0)) .order().by("STRENGTH", desc()) // 按强度降序,确保选最高的边 .limit(1) .inV() ) .until( or( loops().is(eq(3)), // 执行3次遍历后停止,对应原times(3) not(outE("ML_EDGE").has("STRENGTH", gt(0))) // 无符合条件的边时停止 ) )
方案2:确保叶子节点场景返回结果
如果方案1在遇到叶子节点时仍返回空,说明遍历器因无后续边中断,可通过emit()输出所有中间顶点,再取最后一个:
g.V().has('ID','id') .emit() // 输出遍历路径上的所有顶点 .repeat( outE("ML_EDGE").has("STRENGTH", gt(0)) .order().by("STRENGTH", desc()) .limit(1) .inV() ) .until( or( loops().is(eq(3)), not(outE("ML_EDGE").has("STRENGTH", gt(0))) ) ) .tail(1) // 仅保留最终到达的顶点
关于loops()计数的说明
原查询的times(3)表示执行3次遍历步骤,对应until中的loops().is(eq(3))——因为loops()从0开始计数,每执行一次repeat体递增1,执行3次后loops()等于3,触发停止条件。
如果需要执行1次遍历(对应原times(1)),使用until(loops().is(eq(1)))即可,若起点无符合条件的边,方案2会返回起点本身,避免空结果。
内容的提问来源于stack exchange,提问作者Naveen Raj
相关产品推荐
相关产品推荐

