我想通过删除不必要的节点来稍微整理一下我的图形数据库。在一种情况下,不必要的节点是节点A和C之间的节点B,其中B与节点C具有相同的名称,并且没有其他传入关系。我遇到了限制访问边缘数量的Cypher查询的麻烦。
第一部分很简单:
MATCH (n1:TypeA)<-[r1:Inside]-(n2:TypeB)<-[r2:Inside]-(n3:TypeC)
WHERE n2.name = n3.name
基于其他SE问题(尤其是this one),我然后尝试执行以下操作:
WITH n2, collect(r2) as rr
WHERE length(rr) = 1
RETURN n2
但是这也会返回具有多个传入边缘的节点。看来我在长度上的WHERE
子句并未过滤返回的n2
节点。我尝试了其他在网上找到的东西,但它们要么不返回,要么不返回
语法在当前版本中不再正确。
找到与模式匹配的n2
节点后,我想将n3
直接连接到n1
和DETACH DELETE n2
。同样,当我不需要限制n2
的入局边数时,我很容易做到这一点。上一个问题有FOREACH (r IN rr | DELETE r)
,但是我想分离删除n2
节点,而不仅仅是删除那些边缘。我不知道如何正确地调整它以在连接到r
的节点上进行操作,并且我当然想确保在删除任何内容之前找到正确的节点,因为Neo4j缺少基本的撤消功能(但是您可以出于某种疯狂的原因,请在RETURN
中放入FOREACH
命令。
如何使用Cypher按传入边缘的数量过滤路径上的节点?
我认为我可以在py2neo中做到这一点,方法是首先收集所有与模式匹配的n1,n2,n3
三元组,然后遍历每个返回的记录,如果n2
仅具有一个传入边缘,则将它们添加到列表中。然后遍历该列表并执行修剪操作,但是如果可以用纯Cypher进行,那么我想知道如何做,因为我需要进行许多类似的调整。
答案 0 :(得分:1)
您需要在path
语句中传递WITH
。
MATCH path = (n1:Ward)<-[r1:PARTOF]-(n2:Unknown)<-[r2:PARTOF]-(n3:Chome)
WHERE n2.name = n3.name
WITH path, size((n2)<-[:PARTOF]-()) as degree
WHERE degree = 1
RETURN path
或更短一些:
MATCH path = (n1:Ward)<-[r1:PARTOF]-(n2:Unknown)<-[r2:PARTOF]-(n3:Chome)
WHERE n2.name = n3.name
AND size((n2)<-[:PARTOF]-()) = 1
RETURN path
答案 1 :(得分:0)
借鉴this answer的一些见识,我想到了一个似乎可行的方法。
MATCH path = (n1:Ward)<-[r1:PARTOF]-(n2:Unknown)<-[r2:PARTOF]-(n3:Chome)
WHERE n2.name = n3.name
WITH n2, size((n2)<-[:PARTOF]-()) as degree
WHERE degree = 1
MATCH (n1:Ward)<-[r1:PARTOF]-(n2:Unknown)<-[r2:PARTOF]-(n3:Chome)
RETURN n1,n2,n3
我希望并不需要所有部分,也不是一个有效的解决方案,但是我还不知道要改进什么。
例如,我将第一行定义为path
,但是倒数第二行不能使用MATCH path
,我也不知道为什么。
此外,如果我写WITH size((n2)<-[:PARTOF]-()) as degree
(在WITH之后删除n2,
),它不仅返回度数> 1的n2
,而且还返回与其连接的所有节点(甚至更多)比n3
节点)。我不知道为什么会这样,并且WITH的Neo4j文档没有示例或说明来帮助我理解为什么在这里需要n2
。我对Cypher查询的任何改进或如何或为什么的解释都将不胜感激。