Gremlin:AWS Neptune-将图中每个节点的所有叶节点作为CSV获取

Gremlin:AWS Neptune-将图中每个节点的所有叶节点作为CSV获取,gremlin,graph-databases,amazon-neptune,Gremlin,Graph Databases,Amazon Neptune,我有一个简单的图,其中的节点表示下表中的重复记录id Duplicate Id, Original Id A,B B,C C,D X,Y Y,Z 有向图看起来像A->B->C->D,我希望CSV结果如下所示,每个节点都有最终叶节点,没有更多的输出边 A,D B,D C,D X,Z Y,Z 上面是一个简单的场景来解释问题,但是实际数据将有以下更复杂的场景,其中我有24个从a到X的节点,每个节点连接到其他23个节点,具有24C2=276条定向边,对于24个节点中的每一个,我需要没有更多传出边的最

我有一个简单的图,其中的节点表示下表中的重复记录id

Duplicate Id, Original Id
A,B
B,C
C,D
X,Y
Y,Z
有向图看起来像A->B->C->D,我希望CSV结果如下所示,每个节点都有最终叶节点,没有更多的输出边

A,D
B,D
C,D
X,Z
Y,Z
上面是一个简单的场景来解释问题,但是实际数据将有以下更复杂的场景,其中我有24个从a到X的节点,每个节点连接到其他23个节点,具有24C2=276条定向边,对于24个节点中的每一个,我需要没有更多传出边的最终节点

A,B
A,C
A,D
A,E
A,F
A,G
A,H
A,I
A,J
A,K
A,L
A,M
A,N
A,O
A,P
A,Q
A,R
A,S
A,T
A,U
A,V
A,W
A,X
B,C
B,D
B,E
B,F
B,G
B,H
B,I
B,J
B,K
B,L
B,M
B,N
B,O
B,P
B,Q
B,R
B,S
B,T
B,U
B,V
B,W
B,X
C,D
C,E
C,F
C,G
C,H
C,I
C,J
C,K
C,L
C,M
C,N
C,O
C,P
C,Q
C,R
C,S
C,T
C,U
C,V
C,W
C,X
D,E
D,F
D,G
D,H
D,I
D,J
D,K
D,L
D,M
D,N
D,O
D,P
D,Q
D,R
D,S
D,T
D,U
D,V
D,W
D,X
E,F
E,G
E,H
E,I
E,J
E,K
E,L
E,M
E,N
E,O
E,P
E,Q
E,R
E,S
E,T
E,U
E,V
E,W
E,X
F,G
F,H
F,I
F,J
F,K
F,L
F,M
F,N
F,O
F,P
F,Q
F,R
F,S
F,T
F,U
F,V
F,W
F,X
G,H
G,I
G,J
G,K
G,L
G,M
G,N
G,O
G,P
G,Q
G,R
G,S
G,T
G,U
G,V
G,W
G,X
H,I
H,J
H,K
H,L
H,M
H,N
H,O
H,P
H,Q
H,R
H,S
H,T
H,U
H,V
H,W
H,X
I,J
I,K
I,L
I,M
I,N
I,O
I,P
I,Q
I,R
I,S
I,T
I,U
I,V
I,W
I,X
J,K
J,L
J,M
J,N
J,O
J,P
J,Q
J,R
J,S
J,T
J,U
J,V
J,W
J,X
K,L
K,M
K,N
K,O
K,P
K,Q
K,R
K,S
K,T
K,U
K,V
K,W
K,X
L,M
L,N
L,O
L,P
L,Q
L,R
L,S
L,T
L,U
L,V
L,W
L,X
M,N
M,O
M,P
M,Q
M,R
M,S
M,T
M,U
M,V
M,W
M,X
N,O
N,P
N,Q
N,R
N,S
N,T
N,U
N,V
N,W
N,X
O,P
O,Q
O,R
O,S
O,T
O,U
O,V
O,W
O,X
P,Q
P,R
P,S
P,T
P,U
P,V
P,W
P,X
Q,R
Q,S
Q,T
Q,U
Q,V
Q,W
Q,X
R,S
R,T
R,U
R,V
R,W
R,X
S,T
S,U
S,V
S,W
S,X
T,U
T,V
T,W
T,X
U,V
U,W
U,X
V,W
V,X
W,X
这是一个使用Neo4j的图形可视化

对于上述情况,每个节点A到W将有X作为最终叶节点

在整个解决方案中,还需要避免循环循环。一步到位可能太难了,但我们希望得到指导

更新:2020-10-15 遍历优化需要在查找从起始节点到叶节点的路径时优化执行

对于下面的数据场景,顶点A和B的结果应为

A,G
A,H
B,G
B,H

从A到G的最短路径是A->C->E->G;当找到到叶节点的任何1条最短路径时,是否可以抑制从A到G的任何进一步遍历?否则将导致不必要的执行,尤其是对于连接节点的较大集群。需要从A到H重复此步骤,其路径将为A->C->F->H,然后防止进一步尝试查找A和H之间的路径


谢谢

根据您提供的内容,可以构建以下图表

g.addV('A').as('a').
  addV('B').as('b').
  addV('C').as('c').
  addV('D').as('d').
  addV('X').as('x').
  addV('Y').as('y').
  addV('Z').as('z').
  addE('dup').from('a').to('b').
  addE('dup').from('b').to('c').
  addE('dup').from('c').to('d').
  addE('dup').from('x').to('y').
  addE('dup').from('y').to('z').
  iterate()  
下面的查询用于查找结果

gremlin> g.V().
           repeat(out().simplePath()).
           until(__.not(out())).
           path().
             by(label).
           local(
             unfold().
             union(
               limit(1),
               tail()).
             fold())


==>[A,D]
==>[B,D]
==>[C,D]
==>[X,Z]
==>[Y,Z] 
于2020年10月11日更新

使用您提供的更大的数据集,我稍微调整了查询,以便对于每个起始顶点,只找到一条到叶子的路径。这运行得非常快。如果不这样做,从“A”开始,实际上有数以百万计的唯一路径最终到达“X”,这就是为什么前面的查询变得如此复杂

gremlin> g.V().
......1>   local(
......2>     repeat(out().simplePath()).
......3>     until(__.not(out())).
......4>     path().
......5>       by(label).
......6>       limit(1)).
......7>   local(
......8>     unfold().
......9>     union(
.....10>       limit(1),
.....11>       tail()).
.....12>     fold())

==>[A,X]
==>[B,X]
==>[C,X]
==>[D,X]
==>[E,X]
==>[F,X]
==>[G,X]
==>[H,X]
==>[I,X]
==>[J,X]
==>[K,X]
==>[L,X]
==>[M,X]
==>[N,X]
==>[O,X]
==>[P,X]
==>[Q,X]
==>[R,X]
==>[S,X]
==>[T,X]
==>[U,X]
==>[V,X]
==>[W,X]
纯粹出于兴趣,下面的查询显示了图中高度连接的扇形图

gremlin> g.V().group().by(label).by(local(out().label().order().fold())).unfold()

==>A=[B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X]
==>B=[C, D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X]
==>C=[D, E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X]
==>D=[E, F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X]
==>E=[F, G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X]
==>F=[G, H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X]
==>G=[H, I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X]
==>H=[I, J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X]
==>I=[J, K, L, M, N, O, P, Q, R, S, T, U, V, W, X]
==>J=[K, L, M, N, O, P, Q, R, S, T, U, V, W, X]
==>K=[L, M, N, O, P, Q, R, S, T, U, V, W, X]
==>L=[M, N, O, P, Q, R, S, T, U, V, W, X]
==>M=[N, O, P, Q, R, S, T, U, V, W, X]
==>N=[O, P, Q, R, S, T, U, V, W, X]
==>O=[P, Q, R, S, T, U, V, W, X]
==>P=[Q, R, S, T, U, V, W, X]
==>Q=[R, S, T, U, V, W, X]
==>R=[S, T, U, V, W, X]
==>S=[T, U, V, W, X]
==>T=[U, V, W, X]
==>U=[V, W, X]
==>V=[W, X]
==>W=[X]
==>X=[]
计数(将这些数字相乘得到一个大数字)解释了为什么从“a”中查找所有路径是一个昂贵的查询。请注意,
simplePath
步骤帮助我们确保不遵循任何循环。在此数据集中,从任何顶点到“X”的路径数最终为2^(C-1),其中C是给定起点下列表中的数字

gremlin> g.V().group().by(label).by(local(out().count())).unfold()

==>A=23
==>B=22
==>C=21
==>D=20
==>E=19
==>F=18
==>G=17
==>H=16
==>I=15
==>J=14
==>K=13
==>L=12
==>M=11
==>N=10
==>O=9
==>P=8
==>Q=7
==>R=6
==>S=5
==>T=4
==>U=3
==>V=2
==>W=1
==>X=0

您是否正在实施版本化存储系统,在您的示例中,“B”是“a”的早期版本?你能列出一个更复杂的图表来说明你所说的多叶节点和循环循环是什么意思吗?一般来说,循环循环不适合在图中处理,但可能您的情况需要它。你应该努力做到这一点,在一个单一的步骤,除了更简单和更高性能的代码,这也将保持酸保证海王星。一个额外的澄清问题。您是否在问如何编写一个Gremlin查询来生成问题中显示的第二组对?如果是这样的话,如果您可以包括一些示例Gremlin
addV
addE
步骤,这些步骤可以构建一个代表您的用例的小型图,这将是非常有用的。上下文:id是对应于客户分析数据的主键。第一条记录意味着,记录A是B(同一客户)的重复项(基于复杂标准),因此删除A并保留B。重复项由系统成对标识,该系统获取数据集并返回数据集中重复记录的组合。业务规则定义复制对中的2条记录中应保留哪些记录以及删除哪些记录。关于多个叶节点;我可以有像A->B->C->D&A->B->E这样的数据,在这种情况下,A有两个叶节点;D、 E(不再有对外关系)这在功能上意味着不清楚应保留哪些重复记录,它是D或E。最终的数据集将用于从外部系统清理数据,该系统获取2条记录的id,并删除其中一条记录&保留另一条记录(可选地将数据从删除的记录复制到保留记录中),其中保留的记录缺少属性值。如果系统处理B、C删除B并保留C,然后找到A、B;它将尝试删除A并更新B,当B不存在时将失败,因此我必须确定每个节点将折叠到的最终节点。非常感谢您的回复。我有大约24k个顶点和大约26k条边。我的Neptune服务器有250GB内存和64个CPU,无法执行上述查询,我确保没有循环循环,因此需要进一步改进。我还试图限制为一个由24个节点组成的集群,这些节点相互链接,总共有24c2条边,但查询将永远持续运行。g、 V('0012K00001heOMhQAM')。重复(out().simplePath())。直到(uuuu.not(out())).path().by(label)。本地(unfold().union(limit(1),tail()).fold())如果将
直到
步骤替换为类似于
倍(3)
的简单测试,会发生什么?如果可行,请尝试
次(4)
等。从那里到所有可能叶节点的路径有多深?最大深度为24。您是否能够使用稍大的数据集更新问题?如果不查看数据,很难知道问题可能是什么。如果这是不可能的,您可能想打开一个支持案例或张贴到海王星支持论坛,以便支持工程师可以帮助您。感谢您的回复。我用更大的数据集更新了这个问题。当我对一个由24个节点组成的集群运行查询时,需要花费太多的时间,因此我猜测我们可以通过限制第二跳来选择一个未连接到起始节点的节点进行优化,例如,在有24个节点的数据中,如问题中给出的,评估a的路径应该是;A->B/C/D…X[23个选项