使用 Gremlin (AWS Neptune),如何从具有特定条件的起始节点遍历边获取长度为 n 的所有路径?
Using Gremlin (AWS Neptune), how can I get all paths of length n from a starting node traversing edges with specific criteria?
从节点 1 开始,我想 return 所有路径(边和顶点,id/label/properties)在任何出站边之后的 n 跳内,或者在入站边之后 属性 谓词 (p > 50).
理想情况下,路径不应包含任何循环,因此路径不应包含相同节点两次。
属性 p 并非出现在每条边上。
g.addV().property(id, 1).as('1').
addV().property(id, 2).as('2').
addV().property(id, 3).as('3').
addV().property(id, 4).as('4').
addV().property(id, 5).as('5').
addV().property(id, 6).as('6').
addV().property(id, 7).as('7').
addV().property(id, 8).as('8').
addE('pointsAt').from('1').to('2').
addE('pointsAt').from('3').to('1').
addE('pointsAt').from('4').to('1').property('p', 10).
addE('pointsAt').from('5').to('1').property('p', 100).
addE('pointsAt').from('2').to('6').
addE('pointsAt').from('7').to('2').
addE('pointsAt').from('8').to('2').property('p', 100).
iterate()
假设我们从顶点 1 开始,路径如下所示:
1>2
1>2>6
1>2>8
1>5
- 1-2 包含在内 因为它是出站
- 1-3 被排除在外,因为它是入站 1 并且没有 p
- 1-4 被排除,因为它是入站且 (p > 50) 为假
- 1-5 包含在内 因为它是入站且 (p > 50) 为真
- 2-6 包含在内 因为它是出站
- 2-7 被排除在外,因为它是入站 2 并且没有 p
- 2-8 包括在内 因为它入站 2 并且 p > 50
我尝试过许多不同的方法,但似乎无法找到任何接近我正在寻找的方法。
我相信这就是您要找的:
g.V(1).
repeat(
union(
outE(),inE().has('p',gt(50))
).
otherV().simplePath()).
emit().
times(2).
path().
by(valueMap().with(WithOptions.tokens))
repeat() 和 times() 步骤表明这是一个深度为 2 的递归遍历。union() 步骤和包含的参数符合您的要求,以包括所有传出边和仅带有 p 的传入边属性 大于 50。emit() 步骤强制 repeat() 步骤流式传输所有找到的路径。如果你不包括这个,你只会找到长度为 2 的路径(在 times() 步骤中声明)。
总结一下,我们使用 path() 和 by() 输出找到的路径以及路径中每个顶点和边的所有 ID、标签和属性。
您提供的图形的输出如下所示:
==>[[id:1,label:vertex],[id:0,label:pointsAt],[id:2,label:vertex]]
==>[[id:1,label:vertex],[id:3,label:pointsAt,p:100],[id:5,label:vertex]]
==>[[id:1,label:vertex],[id:0,label:pointsAt],[id:2,label:vertex],[id:4,label:pointsAt],[id:6,label:vertex]]
==>[[id:1,label:vertex],[id:0,label:pointsAt],[id:2,label:vertex],[id:6,label:pointsAt,p:100],[id:8,label:vertex]]
从节点 1 开始,我想 return 所有路径(边和顶点,id/label/properties)在任何出站边之后的 n 跳内,或者在入站边之后 属性 谓词 (p > 50).
理想情况下,路径不应包含任何循环,因此路径不应包含相同节点两次。
属性 p 并非出现在每条边上。
g.addV().property(id, 1).as('1').
addV().property(id, 2).as('2').
addV().property(id, 3).as('3').
addV().property(id, 4).as('4').
addV().property(id, 5).as('5').
addV().property(id, 6).as('6').
addV().property(id, 7).as('7').
addV().property(id, 8).as('8').
addE('pointsAt').from('1').to('2').
addE('pointsAt').from('3').to('1').
addE('pointsAt').from('4').to('1').property('p', 10).
addE('pointsAt').from('5').to('1').property('p', 100).
addE('pointsAt').from('2').to('6').
addE('pointsAt').from('7').to('2').
addE('pointsAt').from('8').to('2').property('p', 100).
iterate()
假设我们从顶点 1 开始,路径如下所示:
1>2
1>2>6
1>2>8
1>5
- 1-2 包含在内 因为它是出站
- 1-3 被排除在外,因为它是入站 1 并且没有 p
- 1-4 被排除,因为它是入站且 (p > 50) 为假
- 1-5 包含在内 因为它是入站且 (p > 50) 为真
- 2-6 包含在内 因为它是出站
- 2-7 被排除在外,因为它是入站 2 并且没有 p
- 2-8 包括在内 因为它入站 2 并且 p > 50
我尝试过许多不同的方法,但似乎无法找到任何接近我正在寻找的方法。
我相信这就是您要找的:
g.V(1).
repeat(
union(
outE(),inE().has('p',gt(50))
).
otherV().simplePath()).
emit().
times(2).
path().
by(valueMap().with(WithOptions.tokens))
repeat() 和 times() 步骤表明这是一个深度为 2 的递归遍历。union() 步骤和包含的参数符合您的要求,以包括所有传出边和仅带有 p 的传入边属性 大于 50。emit() 步骤强制 repeat() 步骤流式传输所有找到的路径。如果你不包括这个,你只会找到长度为 2 的路径(在 times() 步骤中声明)。
总结一下,我们使用 path() 和 by() 输出找到的路径以及路径中每个顶点和边的所有 ID、标签和属性。
您提供的图形的输出如下所示:
==>[[id:1,label:vertex],[id:0,label:pointsAt],[id:2,label:vertex]]
==>[[id:1,label:vertex],[id:3,label:pointsAt,p:100],[id:5,label:vertex]]
==>[[id:1,label:vertex],[id:0,label:pointsAt],[id:2,label:vertex],[id:4,label:pointsAt],[id:6,label:vertex]]
==>[[id:1,label:vertex],[id:0,label:pointsAt],[id:2,label:vertex],[id:6,label:pointsAt,p:100],[id:8,label:vertex]]