Neo4j Cypher - FOREACH默默地失败了一个无操作的案例'

时间:2016-04-04 15:54:52

标签: neo4j cypher

在密码中,没有一位官员'条件更新。这是使用'案例技巧模拟的。 IF,这是FOREACH中的CASE,如herehere所示。

以下是我正在使用的查询:

MATCH (reaper:REAPER)-[:TO_REAP]->(doomed)
WHERE reaper <> doomed
WITH reaper, doomed
LIMIT 1
OPTIONAL MATCH (doomed)-[x]-(doomed)
DELETE x
WITH reaper, doomed
OPTIONAL MATCH (doomed)-[r]-(related)
DELETE r, doomed
WITH related, reaper
WHERE related <> reaper
FOREACH(ignore_me IN CASE WHEN
    related IS NOT NULL
            THEN [1] ELSE [] END | MERGE (reaper)-[:TO_REAP]->(related))
RETURN 1

此REAPER的目的是删除节点(子图)。我们这样做是通过删除直接连接到它的节点(&#39;注定的节点),然后连接所有注定失败的孩子。节点使用MERGE直接连接到REAPER(相关)。当然,如果没有孩子,我们就没有任何东西可以连接,这就是FOREACH和CASE的用武之地。如果没有孩子(相关),那么人们会期待FOREACH到NO-OP和转到RETURN。

问题是当相关的IS为null时,查询会缩小,并且不会返回ANYTHING,但也不会失败。这是一个问题,因为我们无法确定什么时候没有删除VS.一片叶子&#39;由于此问题,删除了(没有子节点的单个节点)节点。

在尝试诊断问题时,我删除了“如果&#39;语句(FOREACH和CASE),当related为null时,它会抛出错误&#39;其他节点为空&#39;。

我怀疑FOREACH循环在某种程度上正在吃这个错误,即使MERGE在这种情况下根本不应该执行。

我建议有一个可能的neo4j / cypher错误,所以我希望有人进来告诉我我的查询是多么错误和低效XD

编辑:如果您想自己测试此查询,我忘了谈论数据暂存。

这会让您体验我的问题:

CREATE (r:REAPER)
CREATE (r)-[:TO_REAP]->(n)-[:doesntmatter]->(m)
CREATE (r)-[:TO_REAP]->(p)

当您运行删除查询时,您会注意到,对于&#39; n&#39;节点,它将返回1.但对于其他2个节点,m和p(它们是叶节点),它们将被删除,但不会返回任何内容。

1 个答案:

答案 0 :(得分:2)

This info might help.

Cypher handles the following 2 contrived snippets differently. Let's assume that there is no Foo node.

Snippet 1. (The WHERE clause aborts the query, which returns nothing):

OPTIONAL MATCH (n:Foo)
WITH n
WHERE NULL = 123
RETURN 1;

Snippet 2. (The query completes and returns 1):

OPTIONAL MATCH (n:Foo)
WHERE NULL = 123
RETURN 1;

This difference in behavior may be what is causing your issue.

However, Cypher requires that you use a WITH to separate a DELETE from a subsequent MATCH or WHERE clause.

One way to work around this might be to just move the last WITH clause up by 2 lines (right after its corresponding OPTIONAL MATCH), so that it will not abort the query:

MATCH (reaper:REAPER)-[:TO_REAP]->(doomed)
WHERE reaper <> doomed
WITH reaper, doomed
LIMIT 1
OPTIONAL MATCH (doomed)-[x]-(doomed)
DELETE x
WITH reaper, doomed
OPTIONAL MATCH (doomed)-[r]-(related)
WHERE related <> reaper
DELETE r, doomed
WITH related, reaper
FOREACH(ignore_me IN CASE WHEN
    related IS NOT NULL
            THEN [1] ELSE [] END | MERGE (reaper)-[:TO_REAP]->(related))
RETURN 1