Performance 在neo4j中使用FOREACH时删除关系
我需要删除在FOREACH上迭代的特定类型的节点的关系 详情如下:Performance 在neo4j中使用FOREACH时删除关系,performance,foreach,neo4j,Performance,Foreach,Neo4j,我需要删除在FOREACH上迭代的特定类型的节点的关系 详情如下: PROFILE MATCH (n:Label1)-[r1:REL1]-(a:Label2) WHERE a.prop1 = 2 WITH n WITH COLLECT(n) AS rows WITH [a IN rows WHERE a.prop2 < 1484764200] AS less_than_rows, [b IN rows WHERE b.prop2 = 1484764200 AND b.prop3
PROFILE MATCH (n:Label1)-[r1:REL1]-(a:Label2)
WHERE a.prop1 = 2
WITH n
WITH COLLECT(n) AS rows
WITH [a IN rows WHERE a.prop2 < 1484764200] AS less_than_rows,
[b IN rows WHERE b.prop2 = 1484764200 AND b.prop3 < 2] AS other_rows
WITH size(less_than_rows) + size(other_rows) AS count, less_than_rows, other_rows
FOREACH (sub IN less_than_rows |
MERGE (sub)-[r:REL2]-(:Label2)
DELETE r
MERGE(l2:Label2{id:540})
MERGE (sub)-[:APPEND_TO {s:0}]->(l2)
SET sub.prop3=1, sub.prop2=1484764200)
WITH DISTINCT other_rows, count
FOREACH (sub IN other_rows |
MERGE(l2:Label2{id:540})
MERGE (sub)-[:APPEND_TO {s:0}]->(l2)
SET sub.prop3=sub.prop3+1)
RETURN count
配置文件匹配(n:Label1)-[r1:REL1](a:Label2)
其中a.prop1=2
与n
以COLLECT(n)作为行
其中[a在a.prop2<1484764200]小于_行的行中,
[b在b.prop2=1484764200和b.prop3<2的行中]与其他_行一样
以大小(小于等于行)+大小(其他行)作为计数,小于等于行,其他行
FOREACH(子行数小于
合并(sub)-[r:REL2]-(:Label2)
删除r
合并(l2:Label2{id:540})
合并(sub)-[:将_附加到{s:0}]->(l2)
设置sub.prop3=1,sub.prop2=1484764200)
对于不同的其他_行,计数
FOREACH(其他行中的子行)
合并(l2:Label2{id:540})
合并(sub)-[:将_附加到{s:0}]->(l2)
设置sub.prop3=sub.prop3+1)
返回计数
因为FOREACH不支持MATCH,所以我使用MERGE来实现它。但是当我执行它时,它非常慢(大约需要1分钟)。
但如果我在没有使用out FOREACH(停止向上推)的情况下超过,它将提供大约1秒的时间
问题::显然是FOREACH或in-FOREACH内部操作的问题。
我想删除一个特定关系,创建另一个关系,并将一些属性设置为node。
注意:我显示了total查询,因为有没有其他方法可以达到相同的要求(在这个FOREACH中,我尝试了CASE-WHEN)代替FOREACH,您可以展开行集合并处理这些行。您还可以使用可选的匹配,而不是合并,这样可以避免在找不到匹配项时出现“合并”的回退创建行为。看看这两者的比较:
PROFILE
MATCH (n:Label1)-[:REL1]-(a:Label2)
WHERE a.prop1 = 2
WITH COLLECT(n) AS rows
WITH [a IN rows WHERE a.prop2 < 1484764200] AS less_than_rows,
[b IN rows WHERE b.prop2 = 1484764200 AND b.prop3 < 2] AS other_rows
WITH size(less_than_rows) + size(other_rows) AS count, less_than_rows, other_rows
// faster to do it here, only 1 row so it executes once
MERGE(l2:Label2{id:540})
UNWIND less_than_rows as sub
OPTIONAL MATCH (sub)-[r:REL2]-(:Label2)
DELETE r
MERGE (sub)-[:APPEND_TO {s:0}]->(l2)
SET sub.prop3=1, sub.prop2=1484764200
WITH DISTINCT other_rows, count, l2
UNWIND other_rows as sub
MERGE (sub)-[:APPEND_TO {s:0}]->(l2)
SET sub.prop3=sub.prop3+1
RETURN count
PROFILE
匹配(n:Label1)-[:REL1]-(a:Label2)
其中a.prop1=2
以COLLECT(n)作为行
其中[a在a.prop2<1484764200]小于_行的行中,
[b在b.prop2=1484764200和b.prop3<2的行中]与其他_行一样
以大小(小于等于行)+大小(其他行)作为计数,小于等于行,其他行
//在这里执行速度更快,只有一行,因此它执行一次
合并(l2:Label2{id:540})
将小于_的行作为子行展开
可选匹配(sub)-[r:REL2]-(:Label2)
删除r
合并(sub)-[:将_附加到{s:0}]->(l2)
设置sub.prop3=1,sub.prop2=1484764200
具有不同的其他_行、计数、l2
将其他_行作为子行展开
合并(sub)-[:将_附加到{s:0}]->(l2)
设置sub.prop3=sub.prop3+1
返回计数
我注意到您最初的查询有几点:
应该从两个MERGE(l2:Label2{id:540})
子句中移出,因为它只需要执行一次。这会减慢查询速度。事实上,如果您希望节点已经存在,可以使用FOREACH
匹配
可能不会执行您想要的操作,因为它只会匹配MERGE(sub)-[:APPEND_TO{s:0}]->(l2)
属性仍然为s
的现有关系。如果0
不是s
,则最终将创建一个附加关系。为确保存在单个关系并且其0
值(重置为)s
,您应该从模式中删除0
测试,并使用{s:0}
设置SET
值;这也会加快合并的速度,因为它不需要进行属性值测试s
cybersam在将l2的合并从循环中移出方面有一个很好的观点。尽管我的查询没有FOREACH,但我将其移到了展开上方,因此它只在一行上执行一次,而不是在展开后的每一行上执行一次。
PROFILE
MATCH (n:Label1)-[:REL1]-(a:Label2)
WHERE a.prop1 = 2
WITH COLLECT(n) AS rows
WITH
[a IN rows WHERE a.prop2 < 1484764200] AS less_than_rows,
[b IN rows WHERE b.prop2 = 1484764200 AND b.prop3 < 2] AS other_rows
WITH size(less_than_rows) + size(other_rows) AS count, less_than_rows, other_rows
MERGE(l2:Label2 {id:540})
FOREACH (sub IN less_than_rows |
MERGE (sub)-[r:REL2]-(:Label2)
DELETE r
MERGE (sub)-[r2:APPEND_TO]->(l2)
SET r2.s = 0, sub.prop3 = 1, sub.prop2 = 1484764200)
WITH DISTINCT l2, other_rows, count
FOREACH (sub IN other_rows |
MERGE (sub)-[r3:APPEND_TO]->(l2)
SET r3.s = 0, sub.prop3 = sub.prop3+1)
RETURN count;
PROFILE
MATCH (n:Label1)-[:REL1]-(a:Label2)
WHERE a.prop1 = 2
WITH COLLECT(n) AS rows
WITH
[a IN rows WHERE a.prop2 < 1484764200] AS less_than_rows,
[b IN rows WHERE b.prop2 = 1484764200 AND b.prop3 < 2] AS other_rows
WITH size(less_than_rows) + size(other_rows) AS count, less_than_rows, other_rows
MERGE(l2:Label2 {id:540})
FOREACH (sub IN less_than_rows |
MERGE (sub)-[r:REL2]-(:Label2)
DELETE r
MERGE (sub)-[r2:APPEND_TO]->(l2)
ON CREATE SET r2.s = 0
SET sub.prop3 = 1, sub.prop2 = 1484764200)
WITH DISTINCT l2, other_rows, count
FOREACH (sub IN other_rows |
MERGE (sub)-[r3:APPEND_TO]->(l2)
ON CREATE r3.s = 0
SET sub.prop3 = sub.prop3+1)
RETURN count;