Amazon Neptune中用Gremlin查询选定节点2-4步节点的正确方法
问题:检索选定节点2-4步之外的所有节点(基于最短路径)
我需要检索选定节点2到4步之外的所有节点,由于图结构连接紧密,尝试通过最短路径进行查询。我编写了两段包含repeat().times(2)的Gremlin语句,但未得到正确结果;切换查询目标后仅返回源节点。请问在Amazon Neptune的Jupyter Graph Notebook中,实现该需求的正确方法是什么?
尝试的查询代码
第一段查询
g.V().has('name', 'a').store('x') .emit().repeat(outE().inV().where(without('x')).aggregate('x')).times(2).as('exclude') .emit().repeat(outE().inV().where(without('x')).aggregate('x')).times(2).as('keep') .select('keep') .values('name') .dedup()
第二段查询
g.V().has('name', 'a').store('x') .emit().repeat(outE().inV().where(without('x')).aggregate('x')).times(2).as('exclude') .emit().repeat(outE().inV().where(without('x')).aggregate('x')).times(2).as('keep') .select('exclude') .values('name') .dedup()
正确实现方法
你的问题在于重复使用repeat().times(2)且共享同一个aggregate('x')集合,导致后续遍历无法正确获取更远的节点。要筛选最短路径为2-4步的节点,有两种可靠实现思路:
思路1:遍历筛选路径步数
通过遍历所有可达节点,直接筛选路径步数在2-4之间的结果:
g.V().has('name', 'a') .repeat(out().simplePath()) .emit().until(loops().is(gt(4))) .filter(path().count(local).minus(1).is(between(2,4))) .values('name') .dedup()
repeat(out().simplePath()):向外遍历节点,simplePath()避免循环访问emit().until(loops().is(gt(4))):遍历过程中发射所有节点,直到步数超过4(覆盖我们需要的范围)filter(path().count(local).minus(1).is(between(2,4))):路径中节点数减1即为步数,筛选2-4步的节点values('name').dedup():提取名称并去重,避免同一节点被多条路径匹配
思路2:严格基于最短路径
如果需要确保返回的节点没有更短路径可达(仅保留最短路径为2-4步的节点),可以使用shortestPath()计算距离后筛选:
g.V().has('name', 'a').as('source') .V() .where(neq('source')) .shortestPath() .with(shortestPath.target, 'source') .with(shortestPath.distance, 1) .where(select('distance').is(between(2,4))) .select('v') .values('name') .dedup()
shortestPath():计算当前节点到源节点的最短路径距离with(shortestPath.distance, 1):设定每步路径距离为1(默认规则)where(select('distance').is(between(2,4))):筛选最短路径距离在2-4之间的节点
内容的提问来源于stack exchange,提问作者Herman Yuen
相关产品推荐
相关产品推荐

