在neo4j中删除具有单一关系的叶节点

时间:2014-04-10 21:08:50

标签: neo4j cypher

我正在尝试删除Neo4j中的叶节点,但仅限于那些具有单个传入关系的节点。 (我太近了。)

我有一个查询返回我想删除的确切节点。但是,当我用DELETE替换RETURN时,它会删除超过查询返回的内容。这是完整的序列:

neo4j-sh (?)$ match (n)-[r]->(p)  return n, r, p ;
+------------------------------------------------------------+
| n                    | r            | p                    |
+------------------------------------------------------------+
| Node[2164]{name:"a"} | :has[2616]{} | Node[2165]{name:"b"} |
| Node[2164]{name:"a"} | :has[2617]{} | Node[2166]{name:"c"} |
| Node[2166]{name:"c"} | :has[2619]{} | Node[2168]{name:"e"} |
| Node[2167]{name:"d"} | :has[2618]{} | Node[2165]{name:"b"} |
+------------------------------------------------------------+

此查询非常完美:

neo4j-sh (?)$ match ()-[r:has]->(n)
>   with n,count(r) as rel_cnt
>   where rel_cnt = 1 and NOT (n)-->()
>   return n.name, rel_cnt;
+------------------+
| n.name | rel_cnt |
+------------------+
| "e"    | 1       |
+------------------+

但是这个删除删除了2个节点和3个关系?

neo4j-sh (?)$ match ()-[r:has]->(n)
>   with n, r, count(r) as rel_cnt
>   where rel_cnt = 1 and NOT (n)-->()
>   delete n, r;
+-------------------+
| No data returned. |
+-------------------+
Nodes deleted: 2
Relationships deleted: 3

这就是剩下的

neo4j-sh (?)$ match (n)-[r]->(p)  return n, r, p ;
+------------------------------------------------------------+
| n                    | r            | p                    |
+------------------------------------------------------------+
| Node[2164]{name:"a"} | :has[2617]{} | Node[2166]{name:"c"} |
+------------------------------------------------------------+
neo4j-sh (?)$ match (n) return n;
+----------------------+
| n                    |
+----------------------+
| Node[2169]{name:"a"} |
| Node[2171]{name:"c"} |
| Node[2172]{name:"d"} |
+----------------------+

为什么删除了节点'b'?它没有显示在查询结果中。

1 个答案:

答案 0 :(得分:3)

除了RETURN/DELETE之外,查询实际上并不相同。返回查询携带n, count(r)到第二个查询部分,删除查询携带n, r, count(r)。尝试返回删除查询以查看,即运行此

neo4j-sh (?)$ match ()-[r:has]->(n)
>   with n, r, count(r) as rel_cnt
>   where rel_cnt = 1 and NOT (n)-->()
//>   delete n, r;
>   return *;

你会得到像

这样的东西
+-----------------------------------------------+
| n                    | r            | rel_cnt |
+-----------------------------------------------+
| Node[2165]{name:"b"} | :has[2616]{} | 1       |
| Node[2165]{name:"b"} | :has[2618]{} | 1       |
| Node[2168]{name:"e"} | :has[2619]{} | 1       |
+-----------------------------------------------+

结果不同的原因是管道n, count(r)意味着"计数r每n"并且只有一种情况,其中"计数r = n = 1&# 34 ;.但是另一个管道意味着"计算r每n和每r"如果你自己计算或分组某些东西,那么它每次都会成为一个东西。某些内容被删除的原因是它从未匹配或被其他过滤器标准(NOT (n)-->())排除,rel_cnt=1变得无用。


如果要首先计算关系然后有条件地删除它们,可以收集它们,过滤收集大小,然后从集合中删除。尝试像

这样的东西
MATCH ()-[r:has]->(n)
WITH n, collect(r) as rr
WHERE length(rr) = 1 AND NOT n-->()
FOREACH (r IN rr | DELETE r)
DELETE n