繁体   English   中英

neo4j:用一个节点替换具有相同属性的多个节点

[英]neo4j: Replace multiple nodes with same property by one node

假设我在neo4j中有一个节点的属性“名称”。 现在我想通过识别具有相同名称的所有节点来强制执行给定名称的最多一个节点。 更准确地说:如果有三个名称为“dog”的节点,我希望它们只被一个名为“dog”的节点替换,其中:

  1. 从所有原始三个节点收集所有属性。
  2. 是否所有弧都附加到原始的三个节点。

其背景如下:在我的图中,通常有几个同名的节点应被视为“相等”(尽管有些节点具有比其他节点更丰富的属性信息)。 a.name = b.name放在WHERE子句中的速度非常慢。

编辑:我忘了提到我的Neo4j目前是版本2.3.7(我无法更新)。

第二个编辑:节点和可能的弧有一个已知的标签列表。 节点的类型是已知的。

第三次编辑:我想从Java调用上面的“节点崩溃”过程,因此Cypher查询和过程代码的混合也将是一个有用的解决方案。

我认为你需要类似节点的同义词。

1)遍历所有节点并创建节点同义词:

MATCH (N)
WITH N
  MERGE (S:Synonym {name: N.name})
  MERGE (S)<-[:hasSynonym]-(N)
RETURN count(S);

2)仅使用一个节点删除同义词:

MATCH (S:Synonym)
WITH S
MATCH (S)<-[:hasSynonym]-(N)
WITH S, count(N) as count
WITH S WHERE count = 1
DETACH DELETE S;

3)其余同义词的传输属性和关系(使用apoc ):

MATCH (S:Synonym)
WITH S
MATCH (S)<-[:hasSynonym]-(N)
WITH [S] + collect(N) as nodesForMerge
CALL apoc.refactor.mergeNodes( nodesForMerge );

4)删除Synonym标签:

MATCH (S:Synonym)<-[:hasSynonym]-(N)
CALL apoc.create.removeLabels( [S], ['Synonym'] );

我用以下模式制作了一个测试用例:

CREATE (n1:TestX {name:'A', val1:1})
CREATE (n2:TestX {name:'B', val2:2})
CREATE (n3:TestX {name:'B', val3:3})
CREATE (n4:TestX {name:'B', val4:4})
CREATE (n5:TestX {name:'C', val5:5})

MATCH (n6:TestX {name:'A', val1:1}) MATCH (m7:TestX {name:'B', val2:2}) CREATE (n6)-[:TEST]->(m7)
MATCH (n8:TestX {name:'C', val5:5}) MATCH (m10:TestX {name:'B', val3:3}) CREATE (n8)<-[:TEST]-(m10)

结果如下:

在此输入图像描述

节点B实际上是相同的节点。 这是我的解决方案:

//copy all properties
MATCH (n:TestX), (m:TestX) WHERE n.name = m.name AND ID(n)<ID(m) WITH n, m SET n += m;

//copy all outgoing relations
MATCH (n:TestX), (m:TestX)-[r:TEST]->(endnode) WHERE n.name = m.name AND ID(n)<ID(m) WITH n, collect(endnode) as endnodes
FOREACH (x in endnodes | CREATE (n)-[:TEST]->(x));

//copy all incoming relations
MATCH (n:TestX), (m:TestX)<-[r:TEST]-(endnode) WHERE n.name = m.name AND ID(n)<ID(m) WITH n, collect(endnode) as endnodes
FOREACH (x in endnodes | CREATE (n)<-[:TEST]-(x));

//delete duplicates
MATCH (n:TestX), (m:TestX) WHERE n.name = m.name AND ID(n)<ID(m) detach delete m;

结果输出如下所示:

在此输入图像描述

必须标记您必须知道各种关系的类型。

所有属性都从具有“较高”ID的节点复制到具有“较低”ID的节点。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM