在CYPHER中,CREATE和FOREACH结合使用会产生意想不到的结果



我有一个图,其中版本信息存储为节点之间的[:ADD]或[:REMOVE]关系。我想用另一个模型替换那些日志,基于[:UPDATE]日志,带有属性类型和时间戳。

目前

MATCH (n:tocversion)-[r:ADD]->(m) 
RETURN n.version,id(m)

返回这个(如预期)

n.version,id(m)
1,13
1,14
2,15
2,16
3,17
3,18
3,19
3,20
4,21
4,22

现在我想我可以收集版本和m,并将它们作为在新模型中创建rel的基础。这样的。

MATCH (n:tocversion)-[r:ADD]->(m),(t:toc) 
WITH t,COLLECT(n.version) AS versions, COLLECT(m) AS ms
FOREACH(i IN versions |
    FOREACH(m1 IN [ms[i]]|
        CREATE (t)-[r1:UPDATE {type:"ADD", version:versions[i]}]->(m1)))

然而,我不明白这些荣誉是如何被创造出来的,因为

MATCH (t:toc)-[r:`UPDATE`]->(b) RETURN r.version,r.type,id(b)

返回
r.version,r.type,id(b)
  1,      ADD,      14
  1,      ADD,      14
  2,      ADD,      15
  2,      ADD,      15
  2,      ADD,      16
  2,      ADD,      16
  2,      ADD,      16
  2,      ADD,      16
  3,      ADD,      17
  3,      ADD,      17

而不是预期的

r.version,r.type,id(b)
  1,      ADD,      13
  1,      ADD,      14
  2,      ADD,      15
  2,      ADD,      16
  3,      ADD,      17
  3,      ADD,      18
  3,      ADD,      19
  3,      ADD,      20
  4,      ADD,      21
  4,      ADD,      22

找到了。必须使用RANGE

match (n:tocversion)-[r:ADD]->(m),(t:toc) 
with t,collect(n.version) as versions, collect(m) as ms
foreach(i in RANGE(0, LENGTH(versions)-1) |
    foreach(m1 in [ms[i]]|
        create (t)-[r1:UPDATE5 {type:"ADD", version:versions[i]}]->(m1)))

可能是因为这个:

FOREACH(i IN versions |
FOREACH(m1 IN [ms[i]] |

你的"i"将是:1,1,2,2,3,3,3,3,4,4,如预期的。

但是如果你使用这些作为ms[]集合的索引(这是基于0的),你将会看到ms[] ={13,14,15,16,17,…, 22},所以ms[1]永远是14,ms[2]永远是15,ms[3]永远是16,ms[4]永远是17。

你的"foreach"循环需要重新考虑,因为"i"不应该被用作查找"ms"。

事实上,我也不确定"I"应该被用作索引到"版本",你做你的CREATE语句,因为你可能会有类似的问题如上(例如版本[3]将永远是2)。

最新更新