JanusGraph Gremlin使用as与select时图遍历返回非预期结果
问题原因
Gremlin 基于路径流机制执行遍历,每一步操作都会对当前流中的所有路径逐一处理,生成新路径,你遇到的非预期结果由两个因素共同导致:
- 遍历逻辑本身的笛卡尔积展开
你将两个独立查询直接串联的写法,会触发路径的笛卡尔积计算:
- 第一步
g.V().has("id", 2).outE("knows").inV().dedup().as('a')执行完成后,流中存在2条独立路径,分别为a:v[4216]、a:v[8312] - 后续拼接的
.V().has('id', 5).outE('knows').inV().dedup().as('b')会对每条上游路径,都完整执行一次子遍历,共生成4条路径:(a:v[4216],b:v[4216])、(a:v[4216],b:v[8312])、(a:v[8312],b:v[4216])、(a:v[8312],b:v[8312])
- Tinkerpop 版本Bug
你使用的Tinkerpop 3.4.6版本存在路径标签优化缺陷,特定场景下会丢失部分路径的标签取值,错误填充为重复的同值结果,导致最终仅返回2条相同的v[4216],该问题在Tinkerpop 3.5.0及以上版本已修复。
解决方法
如果需要保留第一个查询的完整结果避免路径笛卡尔积影响,需要用fold()将第一个遍历的结果聚合为列表后再执行后续操作,参考正确写法:
g.V().has("id", 2).outE("knows").inV().dedup().fold().as('a') .V().has('id',5).outE('knows').inV().dedup().fold().as('b') .select('a').unfold()
执行后即可返回你预期的v[4216]、v[8312]两个结果。
内容的提问来源于stack exchange,提问作者Hieu Nguyen
相关产品推荐
相关产品推荐

