如何在Neo4j中将一个节点转换为多个关系
我有一个Neo4j数据库,它存储了一些关于科学文章及其作者的信息。我需要按照以下方式重构数据库,如下图所示。每个黄色节点代表一个作者。红色节点是文章。如果作者是同一篇文章的合著者,我需要删除红色节点并连接他们如何在Neo4j中将一个节点转换为多个关系,neo4j,cypher,Neo4j,Cypher,我有一个Neo4j数据库,它存储了一些关于科学文章及其作者的信息。我需要按照以下方式重构数据库,如下图所示。每个黄色节点代表一个作者。红色节点是文章。如果作者是同一篇文章的合著者,我需要删除红色节点并连接他们 TL;TR: MATCH (a1:Author)-[:HAS_WRITTEN]-(:Article)-[:HAS_WRITTEN]-(a2:Author) MERGE (a1)-[:CO_AUTHOR]-(a2) 获取通过至少一篇文章连接的所有作者对:MATCH(a1:author)-[
TL;TR:
MATCH (a1:Author)-[:HAS_WRITTEN]-(:Article)-[:HAS_WRITTEN]-(a2:Author) MERGE (a1)-[:CO_AUTHOR]-(a2)
MATCH(a1:author)-[:HAS_write]-(:article)-[:HAS_write]-(a2:author)
MERGE(a1)-[:CO_AUTHOR](a2)
。看//获取作者的文章
//比较ID以删除重复项
匹配(auth1:Author)-[:HAS_write]->(article:article)id(auth2)
//删除文章节点
删除条款
//合并共同作者关系
合并(auth1)-[:合作作者]->(auth2)
尽管此查询看起来很长,但它应该可以高效地执行您想要的操作:
MATCH (author:Author)-[r:HAS_WRITTEN]->(article:Article)
DELETE r
WITH article, COLLECT(author) AS authors
DELETE article
WITH authors
UNWIND RANGE(0, SIZE(authors)-2) AS i
WITH authors, i
UNWIND RANGE(i+1, SIZE(authors)-1) AS j
WITH authors[i] AS a1, authors[j] AS a2
CREATE (a1)-[:CO_AUTHOR]->(a2)
它首先查找所有已写入的关系并将其删除。然后为每一篇文章
指定作者
,并删除该文章。然后,它在每对共同作者之间创建一个CO_AUTHOR
关系(假设在运行查询之前不存在任何关系,则无需检查现有关系)
[更正]
正如注释中指出的,上面的查询有一个缺陷。如果同一对作者共同撰写了多篇文章,那么他们最终将通过多个共同作者关系连接起来。因此,这将是一个正确的解决方案:
MATCH (author:Author)-[r:HAS_WRITTEN]->(article:Article)
DELETE r
WITH article, COLLECT(author) AS authors
DELETE article
WITH authors
UNWIND RANGE(0, SIZE(authors)-2) AS i
WITH authors, i
UNWIND RANGE(i+1, SIZE(authors)-1) AS j
WITH authors[i] AS a1, authors[j] AS a2
MERGE (a1)-[:CO_AUTHOR]-(a2)
它首先查找所有已写入的
关系并将其删除。然后为每一篇文章
指定作者
,并删除该文章。然后它使用来确保每对共同作者之间都有一个单一的共同作者关系。放松
子句用于避免明显的关系重复。我不是100%确定,但如果两位作者一起写了多篇文章,这将在他们之间创建多个[:CO_AUTHOR]关系。所以我肯定会选择合并。我尝试过这种方式,它似乎在节点之间创建了多个关系。不管怎样,它可能非常有用。我构建了一个查询,计算两个作者之间的多条边的数量,然后将关系的数量指定为权重。谢谢@Graphileon和@cybersam@Graphileon感谢您的有效评论。我在我的答案中添加了一个更正
。
MATCH (author:Author)-[r:HAS_WRITTEN]->(article:Article)
DELETE r
WITH article, COLLECT(author) AS authors
DELETE article
WITH authors
UNWIND RANGE(0, SIZE(authors)-2) AS i
WITH authors, i
UNWIND RANGE(i+1, SIZE(authors)-1) AS j
WITH authors[i] AS a1, authors[j] AS a2
CREATE (a1)-[:CO_AUTHOR]->(a2)
MATCH (author:Author)-[r:HAS_WRITTEN]->(article:Article)
DELETE r
WITH article, COLLECT(author) AS authors
DELETE article
WITH authors
UNWIND RANGE(0, SIZE(authors)-2) AS i
WITH authors, i
UNWIND RANGE(i+1, SIZE(authors)-1) AS j
WITH authors[i] AS a1, authors[j] AS a2
MERGE (a1)-[:CO_AUTHOR]-(a2)