简体   繁体   English

NEO4j Cypher查询返回条件为连接节点数的路径

[英]NEO4j Cypher query to return paths with a condition on the number of connected nodes

I would like to clean up my graph database a bit by removing unnecessary nodes. 我想通过删除不必要的节点来稍微清理我的图形数据库。 In one case, unnecessary nodes are nodes B between nodes A and C where B has the same name as node C and NO OTHER incoming relationships. 在一种情况下,不必要的节点是节点A和C之间的节点B,其中B与节点C具有相同的名称,并且没有其他传入关系。 I am having trouble coming up with a Cypher query that restricts the number of incoming edges. 我在提出限制进入边缘数量的Cypher查询时遇到了麻烦。

The first part was easy: 第一部分很简单:

MATCH (n1:TypeA)<-[r1:Inside]-(n2:TypeB)<-[r2:Inside]-(n3:TypeC)
WHERE n2.name = n3.name

Based on other SE questions (especially this one ) I then tried doing something like: 根据其他SE问题(尤其是这一问题),我然后尝试执行以下操作:

WITH n2, collect(r2) as rr
WHERE length(rr) = 1 
RETURN n2

but this also returned nodes with more than one incoming edge. 但这也会返回具有多个传入边缘的节点。 It seems my WHERE clause on the length is not filtering the returned n2 nodes. 似乎我在长度上的WHERE子句没有过滤返回的n2节点。 I tried a few other things I found online, but they either returned nothing or were no longer syntactically correct in the current version. 我尝试了一些其他在网上找到的东西,但是它们要么不返回任何内容,要么在当前版本中在语法上不再正确。

After I find the n2 nodes that match the pattern, I'll want to connect n3 directly to n1 and DETACH DELETE n2 . 找到与模式匹配的n2节点后,我想将n3直接连接到n1并分离DETACH DELETE n2 Again, I was easily able to do that part when I didn't need the restriction on the number of incoming edges to n2 . 同样,当我不需要将输入边数限制为n2时,我很容易做到这一点。 That previous question has FOREACH (r IN rr | DELETE r) , but I want to detach delete the n2 nodes, not just those edges. 前面的问题具有FOREACH (r IN rr | DELETE r) ,但是我想分离删除n2节点,而不仅仅是这些边缘。 I don't know how to correctly adapt this to operating on the nodes attached to the r s and I certainly want to be sure it's finding the correct nodes before deleting anything since Neo4j lacks basic undo functionality (but you can't put a RETURN command inside a FOREACH for some crazy reason). 我不知道如何正确地适应这个以连接到该节点上操作r S和我当然希望确保它删除任何内容,因为Neo4j的缺乏基本的撤消功能之前找到正确的节点(但你不能把一个RETURNFOREACH内执行命令(出于某种疯狂的原因)。

How do I filter nodes on a path by the number of incoming edges using Cypher? 如何使用Cypher按传入边缘的数量过滤路径上的节点?

I think I can do this in py2neo by first collecting all the n1,n2,n3 triples matching the pattern, then going through each returned record and add them to a list if n2 has only one incoming edge. 我想我可以在py2neo中做到这一点,方法是先收集所有与模式匹配的n1,n2,n3三元组,然后遍历每个返回的记录,如果n2仅具有一个传入边缘,则将它们添加到列表中。 Then go through that list and perform the trimming operation, but if this can be done in pure Cypher, then I'd like to know how because I have a number of similar adjustments to make. 然后遍历该列表并执行修整操作,但是如果可以用纯Cypher完成,那么我想知道如何做,因为我需要进行许多类似的调整。

You need to pass along path in your WITH statement. 您需要在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

Or shorter like this: 或更短的像这样:

MATCH path = (n1:Ward)<-[r1:PARTOF]-(n2:Unknown)<-[r2:PARTOF]-(n3:Chome)
WHERE n2.name = n3.name
AND size((n2)<-[:PARTOF]-()) = 1
RETURN path

Borrowing some insight from this answer I came up with a kludge that seems to work. 这个答案中获得一些见识,我想到了一个似乎可行的方法。

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

I expect that not all parts of that are needed and it isn't an efficient solution, but I don't know enough yet to improve upon it. 我希望并不需要所有部分,也不是一个有效的解决方案,但是我还不知道要改进什么。

For example, I define the first line as path , but I can't use MATCH path in the penultimate line, and I have no idea why. 例如,我将第一行定义为path ,但是我不能在倒数第二行中使用MATCH path ,我也不知道为什么。

Also, if I write WITH size((n2)<-[:PARTOF]-()) as degree (dropping the n2, after WITH) it returns not only the n2 with degree > 1, but also all the nodes connected to them (even more than the n3 nodes). 另外,如果我将WITH size((n2)<-[:PARTOF]-()) as degree (在WITH之后删除n2,则它不仅返回度数> 1的n2 ,而且还返回与其连接的所有节点(甚至比n3节点还多)。 I don't know why it behaves like this and the Neo4j documentation for WITH has no examples or description to help me understand why the n2 is necessary here. 我不知道为什么会这样,并且WITH的Neo4j文档没有示例或描述来帮助我理解为什么在这里需要n2 Any improvements to my Cypher query or explanation of how or why it works would be greatly appreciated. 对于我的Cypher查询的任何改进或对其工作方式原因的解释,将不胜感激。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM