使用apoc.periodic.iterate根据Neo4j中的计算创建新关系

时间:2018-01-05 17:13:46

标签: neo4j graph-algorithm

我对apoc.periodic.iterate非常困惑,我在(s1)和(s2)之间的以下查询中成功使用它来创建一个新链接[r:ALL_TRANSFERRED]:

//CREATE WEIGHTED LINK
CALL apoc.periodic.iterate(
"MATCH (s1)-[:TRANSFER]->(s2) WHERE s1 <> s2 RETURN s1,s2", 
"MERGE (s1)-[r:ALL_TRANSFERRED]->(s2) ON CREATE SET r.weight = 1 ON MATCH SET r.weight = r.weight + 1"
, {batchSize:5000, parallel:false,iterateList:true})

但是当我尝试修改权重时,要根据新变量添加计算,它会创建一些额外的节点吗?让我们假设(s1)和(s2)是与教师有关系的学校,所以我想把学校里的所有教师都算作一个名为 teachers_in_school 的新变量,可以使用在这个计算中。我在尝试:

//CREATE NORMALISED WEIGHTED LINK 
CALL apoc.periodic.iterate(
"MATCH (s1)-[:TRANSFER]->(s2) WHERE s1 <> s2 
WITH s1,s2
MATCH (t:Teacher)-[:HAD]->(c:Contract)-[:WITH]->(s1)
WHERE c.end = 2016
RETURN s1, count(distinct t) as teachers_in_school", 
"MERGE (s1)-[r:ALL_TRANSFERRED]->(s2) ON CREATE SET r.weight = 1 ON MATCH SET r.weight = (r.weight + 1)/teachers_in_school"
, {batchSize:5000, parallel:false,iterateList:true}) 

但是我得到一些额外的节点,其中空标签链接到(s1)和(s2),并且它们之间没有链接[r:ALL_TRANSFERRED]!

1 个答案:

答案 0 :(得分:2)

主要问题是您的第一个iterate语句未返回s2个节点,因此第二个语句最终创建了全新的s2节点。

以下查询的第一个语句返回一个s2s集合,其中包含每个s2的所有s1个节点。它还会为每个s1的教师计算一次。第二个语句使用UNWINDs2s拆分为单个节点,以便可以单独处理它们。

CALL apoc.periodic.iterate(
  "MATCH (s1)-[:TRANSFER]->(s2) WHERE s1 <> s2 
   WITH s1, COLLECT(s2) AS s2s
   MATCH (t:Teacher)-[:HAD]->(c:Contract)-[:WITH]->(s1) WHERE c.end = 2016
   RETURN s1, s2s, COUNT(DISTINCT t) as teachers_in_school", 
  "UNWIND s2s AS s2
   MERGE (s1)-[r:ALL_TRANSFERRED]->(s2)
   ON CREATE SET r.weight = 1
   ON MATCH  SET r.weight = (r.weight + 1)/teachers_in_school",
  {batchSize:5000, parallel:false,iterateList:true}
)