我正在尝试使用以下查询从neo4j中删除数据:
MATCH (c:Customer {customerID: '16af89a6-832b-4bef-b026-eafea3873d69'})
MATCH (c)<-[r:DEPT_OF]-(dept:Dept)-[*]-(n2) WITH r, dept, n2 LIMIT 10
DETACH DELETE r, dept, n2;
当我检查dept节点时,此语句将永远消失并且不会删除任何内容。这里有什么我想念的吗?
答案 0 :(得分:1)
您有一个可变长度路径,但未在此行中指定上限:
MATCH (c)<-[r:DEPT_OF]-(dept:Dept)-[*]-(n2) WITH r, dept, n2 LIMIT 10
这会导致很多遍历。您的数据模型是否允许指定匹配n2
的跃点数的上限。另外,您应为n2
指定一个或多个标签。
此外,您不需要在r
声明中加入DETACH DELETE
。使用DETACH DELETE
时,也将删除正在删除的节点的任何现有关系。
修改强>
模式(dept:Dept)-[*]-(n2)
表示任何长度的双向路径(没有上限)。要在可变长度路径上指定上限,只需使用(dept:Dept)-[*]-(n2)
替换模式的(dept:Dept)-[*1..3]-(n2)
部分。这会将遍历的路径长度限制为(dept:Dept)
和(n2)
之间最多三个关系(尽管这可能不适合您的数据模型)。向模式添加标签和关系方向(适合您的数据模型)也是一件好事,例如:
MATCH (c)<-[r:DEPT_OF]-(dept:Dept)<-[:BELONGS_TO*1..2]-(n2:Product) WITH r, dept, n2 LIMIT 10
答案 1 :(得分:1)
您的查询中存在许多不同的问题。这是我发现的那个。
可变长度路径查询可发现的路径数(假设下限为0或1)大致是最大路径长度的指数函数。也就是说,如果每个相关节点都有M
个关系,并且搜索到的最大深度(或者,如果没有上限,则最大可能深度)为N
,那么在最坏的情况下,这个数字是5
可能的路径是(M ^ N)。例如,如果我们为10
和M
插入N
和9,765,625
,我们会获得MATCH
个可能的路径(以及相同数量的节点和关系)被删除)。这可能是您的查询需要很长时间的主要原因。
第二个主要问题是由于neo4j引擎中的内存不足导致查询完全失败,原因是内存中可能存在大量数据。你显然还没有遇到过这种情况,但你可能会这样。您可以尝试通过仅匹配完整路径(即,最后一个节点没有其他节点连接到的路径)来最小化找到的路径数。我不知道你的数据模型,所以我不能告诉你一个Cypher子句为你的数据做这件事。但是,如果这样做,则必须修改您的查询以使用找到的路径中的所有节点而不仅仅是路径末端节点。
第二个dept
子句仅匹配r
以外至少有一个关系的dept
个节点,因为可变长度路径的默认下限是长度为1.因此,此查询不会删除没有其他关系的0
个节点。您可以通过指定[*0..]
的下限来解决此问题,如:LIMIT 10
。
您的WITH
子句中有dept
,因此您的查询只会尝试删除少数n2
和LIMIT
个节点。此外,由于您不一定要删除完整路径,因此最终可能会出现“已断开连接的子图”,这些子图不再与其他任何内容相关联。因此,您应该删除n2
子句,即使这会使您的查询花费更长时间。
理论上可以(但我不知道您的数据模型)c
与c
相同。如果您的数据允许这样做,但您永远不希望您的查询删除WHERE
,则需要在相关MATCH
子句之后添加MATCH
子句以防止这种情况发生(请参阅下文) )。
由于MATCH
子句过滤掉两次使用相同关系的匹配项,因此第二个r
子句实际上正在做额外的工作以确保每个变量长度中没有任何关系路径匹配MATCH
。由于您的用例不需要此检查(在修复第5项之后),您可以通过拆分第二个r
子句来避免不必要的检查,以便MATCH (c:Customer {customerID: '16af89a6-832b-4bef-b026-eafea3873d69'})
MATCH (c)<-[r:DEPT_OF]-(dept:Dept)
MATCH (dept)-[*0..]-(n2)
WHERE n2 <> c
DETACH DELETE dept, n2;
在其自己的子句中匹配。
以下是第3,4,5,6项的示例修复:
{{1}}
但是,由于上述内容无法解决第1项或第2项,您的查询仍可能需要很长时间和/或失败。如果您对数据模型提供更完整的概念,我们可能能够解决第2项。但是,第1项是主要问题,可能需要重新考虑您的数据模型或可能将删除拆分为多个查询。