neo4j cypher查询删除中间节点并将其所有父节点连接到子节点

时间:2016-08-12 06:53:03

标签: neo4j cypher

如果我通过执行此查询得到一个图形,那么我想删除一个中间节点说'和',并将其前一个节点连接到'子节点',说'db',使用基于的相应传出关系同样'seqid'

MERGE (n:Person { name:  'graph'}) 

MERGE (n:Person { name:  'and'}) 

MERGE (n:Person { name:  'relational'  })

MERGE (n:Person { name: 'nosql'})

MERGE (n:Person { name:  'server'})

MERGE (n:Person { name:  'db'})

MERGE (a:Person { name:  'graph'}) MERGE (b:Person { name:  'and' }) MERGE (a)-[:NEXT{seqid:1}]->(b)

MERGE (a:Person { name:  'and' }) MERGE (b:Person { name:  'db'}) MERGE (a)-[:NEXT{seqid:1 , caps: 'true'}]->(b)

MERGE (a:Person { name:  'relational'}) MERGE (b:Person { name:  'db'}) MERGE (a)-[:NEXT{seqid:1}]->(b)

MERGE (a:Person { name:  'nosql'}) MERGE (b:Person { name:  'db' }) MERGE (a)-[:NEXT{seqid:2, caps: 'true'}]->(b)

MERGE (a:Person { name:  'server'}) MERGE (b:Person { name:  'and' }) MERGE (a)-[:NEXT{seqid:1}]->(b)

MERGE (a:Person { name:  'and' }) MERGE (b:Person { name:  'db'}) MERGE (a)-[:NEXT{seqid:1}]->(b)

MERGE (a:Person { name:  'server'}) MERGE (b:Person { name:  'and'}) MERGE (a)-[:CONNECTS{seqid:2}]->(b)

MERGE (a:Person { name:  'and' }) MERGE (b:Person { name:  'db'}) MERGE (a)-[:CONNECTS{seqid:2, caps: 'true'}]->(b)

即。

(graph)-[:NEXT{seqid:1 , caps: 'true'}]->(db)

(relational)-[:NEXT{seqid:1}]->(db)

(nosql)-[:NEXT{seqid:2, caps: 'true'}]->(db)

(server)-[:NEXT{seqid:1}]->(db)

(server)-[:CONNECTS{seqid:2, caps: 'true'}]->(db)

请帮我解决这个问题.............

(我在嵌入模式下通过java api使用 neo4j 2.3.6 社区版。)

2 个答案:

答案 0 :(得分:0)

这里的障碍是无法动态创建关系类型。您无法检查传入关系,不知道其类型,并创建相同类型的新关系。

如果您知道需要处理的关系类型,并且可以明确地解决这些关系,那么您可以使用Cypher执行此操作。以下是为所有人执行此操作的查询:NEXT关系,将关系的属性从中间节点复制到结束节点,再到新创建的关系:

MATCH (middle:Person{name:'and'})
WITH middle
MATCH (from:Person)-[rFrom:NEXT]->(middle)
WHERE exists(rFrom.seqid)
WITH middle, rFrom, from
MATCH (middle)-[rTo:NEXT]->(to:Person)
WHERE rTo.seqid = rFrom.seqid
WITH middle, rFrom, from, rTo, to
CREATE (from)-[rNew:NEXT]->(to)
SET rNew += rTo
DELETE rFrom

您需要为您感兴趣的每种关系类型重复此操作,并且当您的中间节点没有更多关系时,请删除该节点。

请注意,如果您升级到neo4j 3,则APOC过程库具有图形重构的过程,这将很容易解决此问题。

编辑

将上面的Cypher改为CREATE而不是MERGE。

还删除了从中间节点到下一个节点的关系删除,因为您似乎希望从连接中间节点到下一个节点的关系中获取关系属性,并且因为中间可能存在多个传入关系具有相同类型和id的节点,但只有来自中间节点的具有该类型和id的单个关系。

这意味着您具有相同类型和ID的传入关系的比率不等于相同类型和ID的传出关系,因此我们将在创建新关系时重用这些传出关系。

只有在完成创建新关系之后,才能分离并删除中间节点。

答案 1 :(得分:0)

添加另一个满足所有要求的答案,但需要Neo4j 3.0.x或更高版本。具体来说,这需要来自APOC程序的apoc.create.relationship()程序,这将允许我们创建一个动态类型的关系,该关系由匹配的关系提供。

这将立即处理所有关系(至少是那些带有seqid的关系),所以我们应该可以在最后分离和删除中间节点。

MATCH (middle:Person{name:'and'})
WITH middle
MATCH (from:Person)-[rFrom]->(middle)
WHERE EXISTS(rFrom.seqid)
WITH middle, rFrom, from
MATCH (middle)-[rTo]->(to:Person)
WHERE TYPE(rTo) = TYPE(rFrom) AND rTo.seqid = rFrom.seqid
WITH middle, rFrom, from, rTo, to
CALL apoc.create.relationship(from, TYPE(rFrom), PROPERTIES(rTo), to) YIELD rel
DETACH DELETE middle