在 Neo4j 中使用 apoc.periodic.iterate 基于计算创建新关系
Using apoc.periodic.iterate to create new relationships based on calculation in Neo4j
我对apoc.periodic.iterate很困惑,我在下面的(s1)和(s2)之间的查询中成功地使用它创建了一个新的link [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})
但是我得到了一些带有空标签的额外节点 linked 到 (s1) 和 (s2),并且它们之间没有 link [r:ALL_TRANSFERRED]!
主要问题是您的第一个 iterate
语句没有返回 s2
个节点,因此第二个语句最终创建了全新的 s2
个节点。
以下查询的第一个语句 returns 一个 s2s
集合,其中包含每个 s1
的所有 s2
节点。它还只计算每个 s1
的教师一次。第二条语句使用 UNWIND
将 s2s
分解为单独的节点,以便可以单独处理它们。
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}
)
我对apoc.periodic.iterate很困惑,我在下面的(s1)和(s2)之间的查询中成功地使用它创建了一个新的link [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})
但是我得到了一些带有空标签的额外节点 linked 到 (s1) 和 (s2),并且它们之间没有 link [r:ALL_TRANSFERRED]!
主要问题是您的第一个 iterate
语句没有返回 s2
个节点,因此第二个语句最终创建了全新的 s2
个节点。
以下查询的第一个语句 returns 一个 s2s
集合,其中包含每个 s1
的所有 s2
节点。它还只计算每个 s1
的教师一次。第二条语句使用 UNWIND
将 s2s
分解为单独的节点,以便可以单独处理它们。
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}
)