首页 > 解决方案 > neo4j - 如果关系 = 0,则删除关系后删除节点

问题描述

让我们举个例子:我有一个数据集,里面有互相残杀的凶手。我们有murderer-killed->murderer.

 neo4jClient.Cypher
.Match("(murderer1:MurdererNode)-[k:KILLED]->(murderer2:MurdererNode)
.Where((MurdererNode murderer1) => murderer1.Name == "someName")
.AndWhere((MurdererNode murderer2) => murderer2.Name == "someName2")
.Delete("k")

现在,在我的应用程序中,我正在传递一些参数并删除两个节点之间的“已终止”关系。在执行删除之后,任何一个节点都可能没有传入的“已终止”或传出的“已终止”关系。仅在这种情况下,即当传入和传出都等于 0 时,我想从我的数据库中删除该节点。

删除关系后,我想对参与关系的两个节点执行“IF node.out_relationship.count = 0 and node.in_relationship.count = 0, then DELETE node”。换句话说,我想在我的节点上执行一些关系删除后的工作。

我正在考虑按如下方式增强我的查询:

 neo4jClient.Cypher
.Match("(murderer1:MurdererNode)-[k:KILLED]->(murderer2:MurdererNode)
.Where((MurdererNode murderer1) => murderer1.Name == "someName")
.AndWhere((MurdererNode murderer2) => murderer2.Name == "someName2")
.Delete("k")
.With("murderer1,murderer2")
.Match("(murderer1)-[:KILLED]-()")
.Where("count(murderer1)=0")
.Delete(murderer1)
.Match("(murderer2)-[:KILLED]-()")
.Where("count(murderer2)=0")
.Delete(murderer2)

(显然我可以将查询分解为其他会话,但我认为将所有内容保存在一个会话中,重用节点会更有效。)

无论如何,我不确定这种变化有多大意义,它看起来很丑,感觉就像我向后弯腰一样。

我该如何继续?我将不胜感激任何帮助。谢谢。

标签: c#neo4jgraph-databasesspring-data-neo4jneo4jclient

解决方案


由于您对凶手 1 和凶手 2 的逻辑是相同的,因此如果您为两个凶手创建一个 2 元素列表,然后将它们展开到单个变量,您可以同时将该逻辑应用于他们两个。

用于此的 Cypher 将是:

MATCH (murderer1:MurdererNode)-[k:KILLED]->(murderer2:MurdererNode)
WHERE murderer1.Name = "someName"
 AND murderer2.Name = "someName2"
DELETE k
WITH [murderer1, murderer2] as murderers
UNWIND murderers as murderer // now each on its own row under "murderer"
WITH murderer
WHERE size((murderer)-[:KILLED]-()) = 0
DETACH DELETE murderer // will delete any additional relationships

您还可以使用 FOREACH(在 :KILLED 度为 0 的 2 个凶手的过滤集合上)并在那里执行 DETACH DELETE 而不是使用 UNWIND。

我不完全确定用 neo4jclient 会如何表达,但这应该是一个你可以用来工作的蓝图。


推荐阅读