如何利用边权重控制Apache Gremlin图遍历的顺序?
按边权重绝对值优先的Gremlin图遍历实现方案
需求说明
遍历带权重的有向图,需遵循以下规则:
- 按边权重的绝对值越小优先级越高
- 同权重的边可并行遍历或随机选择
- 目标是让节点值按此规则在图中传播,但目前无法实现按最小权重的可控遍历
基础遍历代码(可正常运行)
traversal = vg.V().has('Value','SomeStartNodeIChose').repeat(outE().otherV().simplePath()).until(has('Value','SomeEndNodeIChose')).path().by('Value').by('Weight');[] :> traversal
错误尝试及报错信息
尝试1
traversal = vg.V().has('Value','AirBnb').repeat(outE().where(min()).otherV().simplePath()).until(has('Value','Comfort')).path().by('Value').by('Update Weight');[]
报错:
org.apache.tinkerpop.gremlin.tinkergraph.structure.TinkerEdge cannot be cast to java.lang.Comparable
尝试2
traversal = vg.V().has('Value','AirBnb').repeat(outE().where('Weight',is(min())).otherV().simplePath()).until(has('Value','Comfort')).path().by('Value').by('Update Weight');[]
报错:
No signature of method: org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.DefaultGraphTraversal.where() is applicable for argument types: (String, org.apache.tinkerpop.gremlin.process.traversal.dsl.graph.DefaultGraphTraversal) values: [Weight, [IsStep(eq([MinGlobalStep]))]]
正确实现方案
核心思路
在repeat步骤中,对当前节点的所有出边按权重绝对值升序排序,优先选择绝对值最小的边;若需随机选择同权重边,可替换为随机采样逻辑。
代码示例
优先选择单条最小权重绝对值的边
traversal = vg.V().has('Value','AirBnb') .repeat( outE() .order().by(values('Weight').abs(), asc) // 按权重绝对值从小到大排序 .limit(1) // 取排序后的第一条(最小绝对值边) .otherV().simplePath() ) .until(has('Value','Comfort')) .path().by('Value').by('Update Weight')
随机选择同权重的最小绝对值边
若存在多条权重绝对值相同的最小边,需要随机选一条,将limit(1)替换为sample(1):
traversal = vg.V().has('Value','AirBnb') .repeat( outE() .order().by(values('Weight').abs(), asc) .sample(1) // 随机采样一条最小绝对值边 .otherV().simplePath() ) .until(has('Value','Comfort')) .path().by('Value').by('Update Weight')
错误原因解释
- 尝试1中
where(min())直接对边对象使用min(),但min()需要针对属性值计算,边对象本身不是Comparable类型,导致类型转换报错。 - 尝试2的
where('Weight', is(min()))语法错误,min()作为全局聚合函数不能直接用于where的条件判断,正确做法是先对边按权重属性排序再筛选。
内容的提问来源于stack exchange,提问作者Lapin Chaman
相关产品推荐
相关产品推荐

