2016-04-04 8 views
1

cypherでは、「公式の」条件付きアップデートはありません。これは、FOREACH内部のケースであり、herehereと示された 'ケーストリック' IFを使用してエミュレートされます。ここでNeo4j Cypher - no-op 'case trick'でサイレントに失敗する

は、私が働いているクエリです:

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の目的は、ノード(部分グラフ)を削除することです。これには、直接接続されているノード(「運命のノード」)を削除し、「破棄」ノードのすべての子ノードをMERGEを使用して直接REAPER(関連)に接続します。もちろん、子どもがいない場合、私たちは外国人と外国人が入ってくる場所はありません。子どもがいない(関連している)人は、外国人にはノー・オペを期待し、戻り値に戻します。

問題は関連するnullで、クエリがクラップアウトされ、何も返されませんが、FAILではありません。 VSを削除するものが何もないと判断できないため、これは問題です。この問題により、「リーフ」ノード(子ノードがない単一ノード)が削除されました。

問題を診断しようとすると、if文(FOREACHとCASE)が削除され、関連がnullの場合、「Other node is null」というエラーがスローされます。

私は、FOREACHループが何らかの形でこのエラーを起こしていると考えています。ただし、その状態でMERGEを実行してはいけません。

私は可能性のNeo4j/CYPHERバグがあることを示唆していますので、私は、誰かが入ってくると、私のクエリはXD

編集でどのように間違っていると非効率的な私に教えたい:私は、データのステージングについて話を忘れてしまいましたこのクエリを自分でテストしたい場合は

この私の問題が発生しますを設定します:

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

あなたが削除クエリを実行すると、あなたは「n」のノードに対して、それが1を返すことに気づく。しかし他のためによ2つのノード、mとp(リーフノード)は削除されますが、何も返されません。

答えて

2

この情報は役に立ちます。

Cypherは次の2つのスニペットを別々に処理します。 Fooノードがないとします。

スニペット1.(WHERE句は何も返さないクエリを、中止します):

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

スニペット2.(クエリが完了し、1を返します):

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

この動作の違いあなたの問題を引き起こしているものかもしれません。

ただし、WITHを使用して、DELETEを次のMATCHまたはWHERE句と区切る必要があります。

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 
+0

ありがとうcybersam:このを回避するために

一つの方法は、、クエリを中止しないようにだけ、(右のはOPTIONAL MATCH対応後)2線で最後WITH句を上に移動するかもしれません!あなたが投稿したものからクエリを少し修正する必要がありました。なぜなら、削除された 'r'は元の:TO_REAP関係を削除していたからです。 where句を移動すると、そのTO_REAP関係は含まれなくなります。だから私は単にそれをさらに上に削除しなければならなかった(ここで私は 'x'を削除する)。それにかかわらず、あなたの診断は正しいです。私はnull値でWITHを実行していたため、クエリがクラッシュしました。編集:また、それは少し混乱していたが、あなたは最後のWITH句を移動すると言った、あなたは最後のWHERE句(それはあなたのクエリでは正しいです)と言っていた。その – brehon1104

+0

を編集したいかもしれませんまた、私はそれがWHERE句のヌルWITHのクエリを中止するとは思わない。これも失敗します。一致(x:THIS_DOESNT_EXIST) x リターン1 |したがって、null変数でWITHを使用すると、クエリが中断するように見えます – brehon1104

関連する問題