用cypher

时间:2016-09-20 12:45:22

标签: neo4j cypher

我有一个700K属性的大型数据库。但有些是重复的,所以我现在想要"清洁"所有这些......

我期待将1+个节点替换为1+个其他节点,并链接该节点可能存在的所有关系。

所以我想做点什么:

MATCH (p:Property) WHERE p.uid IN ['A6271DFB-F0FD-0DF1-6F22-67F7D3164AE6']
WITH p AS sources
MATCH (p2:Property) WHERE p2.uid IN ['51A26A14-74FB-BCFC-FE5C-661A43A9377C','8DCD063C-965D-CC12-6159-E287CD000954']
WITH sources, p2 AS destinations
OPTIONAL MATCH (sources)-[k]->(n) MERGE (destinations)-[y]->(n) SET y=k
WITH sources, destinations
OPTIONAL MATCH (sources)<-[s]-(n) MERGE (destinations)<-[w]-(n) SET w=s
WITH sources
DETACH DELETE sources

当然,它不起作用,因为我需要指定合并的关系类型......但我实际上并不知道它(因为它可能是几种类型,并且取决于类型, rel可能有属性)...

现在,我开发了一个PHP脚本来匹配所有节点+ rels;和FOREACH记录;生成MERGE查询以将它们链接到新节点......但这很慢而且没有优化...

有没有人对此有所了解?

1 个答案:

答案 0 :(得分:1)

以下查询应该适合您。它利用APOC plugin及其apoc.refactor.mergeNodes过程为您合并节点。该过程传递一组节点,将第二个节点(及其关系)合并到第一个节点上,然后删除第二个节点(及其关系),并返回第一个节点。

为了便于说明,下面的两个uid集合都包含多个值;在一个真实世界场景中,两个集合都应该通过parameters传递。

MATCH (src:Property) WHERE src.uid IN ['A6271DFB-F0FD-0DF1-6F22-67F7D3164AE6','A6271DFB-F0FD-0DF1-6F22-123456789012']
WITH COLLECT(src) AS sources
MATCH (dest:Property) WHERE dest.uid IN ['51A26A14-74FB-BCFC-FE5C-661A43A9377C','8DCD063C-965D-CC12-6159-E287CD000954']
CALL apoc.refactor.mergeNodes([dest] + sources) YIELD node
RETURN node;

查询首先将所有源节点收集到sources集合中。然后,它匹配每个目标节点,并使用apoc.refactor.mergeNodes过程将所有源节点合并到每个目标节点。 [dest] + sources语法按顺序生成组合dest节点和sources节点的新集合。)查询返回每个(合并的)目标节点