使用Gremlin API遍历顶点、条件收集属性并达到数量限制时终止的实现方法
Gremlin查询实现方案
你可以用sack()累计状态+choose()分支判断的逻辑实现需求,对应你给出的示例参数,查询写法如下:
// 示例参数:起点id=2,遍历方向out,允许作者['Luc','Kim'],上限3个 g.V(2). // 初始化sack存储符合条件的顶点id,先判断起点是否符合条件 sack(ArrayList).by(choose(has('a', within('Luc', 'Kim')), id(), constant([]))). repeat( // 按指定方向走next边 out('next'). // 符合作者条件就将id加入累计列表,不符合就保持列表不变 choose( has('a', within('Luc', 'Kim')), sack(assign).by(union(sack(), id()).fold()), identity() ) ). // 终止条件:累计id达到上限 或 遍历到路径终点 until(sack().count(local).is(gte(3)).or().out('next').count().is(0)). // 取前N个结果避免超出上限 sack().limit(local, 3)
逻辑说明
sack()用于存储遍历过程中跨迭代的累计状态,专门用来实现你需要的“边遍历边收集符合条件的id”需求choose()做分支判断:符合作者筛选条件就收集id,不符合就直接跳过收集步骤,继续沿路径遍历- 需要切换遍历方向时,直接把代码中的
out('next')替换为in('next')即可 - 作者筛选数组、数量上限都可以直接参数化替换对应位置的固定值即可
上述查询跑你给出的示例数据,输出结果正好是[2,4,5],完全符合预期。
如果你的图数据库支持TinkerPop 3.6及以上版本,还可以用更简洁的aggregate()写法:
g.V(2).has('a', within('Luc', 'Kim')).aggregate('res').by(id). repeat(out('next')). emit(has('a', within('Luc', 'Kim'))). aggregate('res').by(id). until(cap('res').count(local).is(gte(3)).or().out('next').count().is(0)). cap('res').limit(local, 3)
内容的提问来源于stack exchange,提问作者Gilles jr Bisson
相关产品推荐
相关产品推荐

