【问题标题】:NEO4j Cypher query to return paths with a condition on the number of connected nodesNEO4j Cypher 查询以连接节点数为条件返回路径
【发布时间】:2018-11-30 05:34:48
【问题描述】:

我想通过删除不必要的节点来稍微清理一下我的图形数据库。在一种情况下,不必要的节点是节点 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 直接连接到n1DETACH DELETE n2。同样,当我不需要限制 n2 的传入边数时,我很容易做到这一点。上一个问题有FOREACH (r IN rr | DELETE r),但我想分离删除n2 节点,而不仅仅是那些边缘。我不知道如何正确调整它以在附加到rs 的节点上进行操作,我当然想确保它在删除任何内容之前找到正确的节点,因为 Neo4j 缺乏基本的撤消功能(但你不能放出于某种疯狂的原因,FOREACH 中的 RETURN 命令)。

如何使用 Cypher 根据传入边数过滤路径上的节点?

我想我可以在 py2neo 中做到这一点,首先收集与模式匹配的所有 n1,n2,n3 三元组,然后遍历每个返回的记录,如果 n2 只有一个传入边,则将它们添加到列表中。然后浏览该列表并执行修剪操作,但如果这可以在纯 Cypher 中完成,那么我想知道如何进行,因为我有许多类似的调整要做。

【问题讨论】:

    标签: neo4j cypher


    【解决方案1】:

    您需要在您的WITH 语句中传递path

    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
    

    【讨论】:

    • 直接使用WHERE 条件限制入度对我来说是最直观的。根据我能找到的示例和文档,我尝试了几件事,包括上面使用 collect 的代码,但我不知道它可以像这样直接使用。谢谢!
    【解决方案2】:

    借用 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)&lt;-[:PARTOF]-()) as degree(在 WITH 之后删除 n2,),它不仅返回度数 > 1 的 n2,而且还返回所有连接到它们的节点(甚至超过 n3 节点)。我不知道它为什么会这样,并且 WITH 的 Neo4j 文档没有示例或描述来帮助我理解为什么 n2 在这里是必要的。对我的 Cypher 查询的任何改进或如何为什么的解释将不胜感激。

    【讨论】:

    • 您没有在 WITH 声明中传递 path
    • 没错,我尝试在其他任何地方使用路径(在定义它之后)没有返回正确的东西......实际上,如果我离开 path= 部分,上面的代码会返回正确的子图.它与n2, 一起工作,而不是path,但它显然需要一个或另一个,我不知道为什么这是必要的。文档中没有类似的内容,而且我看到的所有示例都没有解释。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-04
    • 1970-01-01
    • 2018-11-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多