2017-10-25 15 views
0

nullの問題が発生しました。NEO4Jオプションnullの場合、照会の戻り値はすべて空です。

//Match gs to searched w 
MATCH (w1:W {name: "****"})-[:REL]->(gs:G) 
WITH w1, COLLECT(DISTINCT gs) AS gsCol, SIZE((w1)-[:REL]-()) AS gCount 
OPTIONAL MATCH (w1)-[:REL]-()-[:SIMILAR*0..1]->(gs:G) 
WITH w1, gsCol, gCount, COLLECT(DISTINCT gs) AS similarGs 
//Match all ws that contain gs in searched w or where similar as wsCol 
OPTIONAL MATCH (w1)-[c2a:REL]->(g4:G)-[c2b:REL|:SIMILAR*0..1]-(ws:W) 
WHERE c2a.amount - 10 < last(c2b).amount < c2a.amount + 10 
WITH w1, gsCol, similarGs, gCount, COLLECT(DISTINCT ws) AS ws2, COLLECT(DISTINCT ws) AS ws3, COLLECT(DISTINCT ws) AS ws4 
//Match ws from wsCol where all gs in new matched ws are same 
UNWIND ws2 as w2 
OPTIONAL MATCH (w2)-[c3:REL]->(g3:G) 
WITH w1, w2, ws3, ws4, gsCol, similarGs, gCount, COLLECT(g3) AS gs3, SIZE((w2)-[:REL]->()) as gCount3, SUM(c3.amount) AS c3amount 
WHERE ALL(x in gs3 WHERE x IN gsCol) 
WITH w1, w2, ws3, ws4, gsCol, similarGs, gCount, gCount3, c3amount 
WHERE gCount3 = gCount AND c3amount = 100 
WITH COLLECT(w2) AS ws2Col, w1, ws3, ws4, gsCol, similarGs, gCount 
//Match ws with gs that are in searched or similar to searched w 
UNWIND ws3 as w3 
WITH w1, w3, ws4, gsCol, similarGs, gCount, ws2Col 
OPTIONAL MATCH (w3)-[c4:REL]->(g4:G) 
WITH w1, w3, ws4, ws2Col, gsCol, similarGs, gCount, COLLECT(g4) AS gs4, SIZE((w3)-[:REL]->()) AS gCount4, SUM(c4.amount) AS c4amount 
WHERE ALL(x in gs4 WHERE x in similarGs) 
WITH w1, w3, ws4, ws2Col, gsCol, similarGs, gCount, gs4, gCount4 
WHERE gCount4 = gCount AND c4amount = 100 AND NOT(w3 IN ws2Col) 
WITH COLLECT(w3) AS ws3Col, w1, w3, ws4, ws2Col, gsCol, gCount, similarGs 
//Match ws where depending on number of gs in w 1 or 2+ gs match searched w 
UNWIND ws4 AS w4 
OPTIONAL MATCH (w4)-[c5b:REL]->(g5:G) 
WITH w1, w4, ws2Col, ws3Col, gsCol, similarGs, gCount, sum(c5b.amount) AS c6amount, SIZE((w4)-[:REL]-()) as gCount5, collect(g5) AS gs5, max(c5b.amount) as c6max 
WHERE ALL(x IN gs5 WHERE x IN gsCol) AND (CASE WHEN gCount > 2 THEN c6amount > 25 ELSE c6amount > 65 END) AND NOT(w4 in ws2Col) AND NOT(w4 in ws3Col) 
WITH COLLECT(w4) AS ws4Col, w1, ws2Col, ws3Col, w4, gsCol, similarGs, gCount, c6amount, gCount5, gs5, c6max 
UNWIND ws2Col AS ws2a UNWIND ws3Col AS ws3a UNWIND ws4Col AS ws4a 
RETURN collect(distinct ws2a) AS match1, collect(distinct ws3a) AS match2, collect(distinct ws4a) AS match3 

があり、W2、W3またはW4はnullを返すことができ、このクエリ内の時間ですそれが動作を期待されているが、これらのいずれかである場合はnull全体の結果がnullであるか

╒════════╤════════╤════════╕ 
│"match1"│"match2"│"match3"│ 
╞════════╪════════╪════════╡ 
│[]  │[]  │[]  │ 
└────────┴────────┴────────┘ 

私はmatch1にいくつかの結果があり、match2がnullの場合にmatch3を参照すると予想されます。

私はcollect(w2)、collect(w3)、およびcollect(w4)なしでクエリを実行しようとしましたが、これによりクエリがタイムアウトまたはヒープサイズを使い果たしてしまいます。

誰もオプションの一致を避ける方法を示唆しています。クエリ内のすべてを削除したり、他のオプションのマッチでnullを返すことはありますか?

EDIT 1 -

は持っているが、クエリを破ることができる点を見つけ...オプションの試合の第二の間に...

AND NOT(w3 IN ws2Col) 

を、私は、この時のリターンを実行する場合でも、 W3がnullの場合ws2Colはnullを返しポイント

EDIT 2 -

@BrunoPeresの答えは、ほとんどがあり、近づいへの大きな一歩を踏み出しました。 COLLECTFILTERに変更して、他のコレクションの1つがnullの場合、これらのコレクションを削除しないようにする必要がありました。ここでこれを遭遇するかもしれない人々の最終的な質問があります。

//Match gs to searched w 
MATCH (w1:W {name: "****"})-[:CONTAINS]->(gs:G) 
WITH w1, COLLECT(DISTINCT gs) AS gsCol, SIZE((w1)-[:CONTAINS]-()) AS gCount 
OPTIONAL MATCH (w1)-[:CONTAINS]-()-[:SIMILAR*0..1]->(gs:G) 
WITH w1, gsCol, gCount, COLLECT(DISTINCT gs) AS similarGs 
//Match all ws that contain gs in searched w or where similar as wsCol 
OPTIONAL MATCH (w1)-[c2a:CONTAINS]->(g4:G)-[c2b:CONTAINS|:SIMILAR*0..1]-(ws:W) 
WHERE c2a.amount - 10 < last(c2b).amount < c2a.amount + 10 
WITH w1, gsCol, similarGs, gCount, COLLECT(DISTINCT ws) AS ws2, COLLECT(DISTINCT ws) AS ws3, COLLECT(DISTINCT ws) AS ws4 
//Match ws from wsCol where all gs in new matched ws are same 
UNWIND ws2 as w2 
OPTIONAL MATCH (w2)-[c3:CONTAINS]->(g3:G) 
WITH w1, w2, ws3, ws4, gsCol, similarGs, gCount, COLLECT(g3) AS gs3, SIZE((w2)-[:CONTAINS]->()) as gCount3, SUM(c3.amount) AS c3amount 
WHERE ALL(x in gs3 WHERE x IN gsCol) 
WITH w1, w2, ws3, ws4, gsCol, similarGs, gCount, gCount3, c3amount 
WHERE gCount3 = gCount AND c3amount = 100 
WITH COLLECT(w2) ELSE ['none'] END AS ws2Col, w1, ws3, ws4, gsCol, similarGs, gCount 
//Match ws with gs that are in searched or similar to searched w 
UNWIND ws3 as w3 
WITH w1, w3, ws4, gsCol, similarGs, gCount, ws2Col 
OPTIONAL MATCH (w3)-[c4:CONTAINS]->(g4:G) 
WITH w1, w3, ws4, ws2Col, gsCol, similarGs, gCount, COLLECT(g4) AS gs4, SIZE((w3)-[:CONTAINS]->()) AS gCount4, SUM(c4.amount) AS c4amount 
WHERE ALL(x in gs4 WHERE x in similarGs) 
WITH w1, w3, ws4, ws2Col, gsCol, similarGs, gCount, gs4, gCount4, c4amount 
WHERE gCount4 = gCount AND c4amount = 100 AND NOT(w3 IS NULL OR w3 IN ws2Col) 
WITH CASE WHEN NOT(w3 IS NULL) THEN COLLECT(w3) ELSE ['none'] END AS ws3Col, w1, w3, ws4, ws2Col, gsCol, gCount, similarGs 
//Match ws where depending on number of gs in w 1 or 2+ gs match searched w 
UNWIND ws4 AS w4 
OPTIONAL MATCH (w4)-[c5b:CONTAINS]->(g5:G) 
WITH w1, w4, ws2Col, ws3Col, gsCol, similarGs, gCount, sum(c5b.amount) AS c6amount, SIZE((w4)-[:CONTAINS]-()) as gCount5, collect(g5) AS gs5, max(c5b.amount) as c6max, ws2Col + ws3Col AS wsC 
WHERE ALL(x IN gs5 WHERE x IN gsCol) AND (CASE WHEN gCount > 2 THEN c6amount > 25 ELSE c6amount > 65 END) AND NOT(w4 in ws2Col OR w4 in ws3Col) 
WITH CASE WHEN w4 IS NULL THEN ['none'] ELSE COLLECT(w4) END AS ws4Col, w1, ws2Col, ws3Col, w4, gsCol, similarGs, gCount, c6amount, gCount5, gs5, c6max 
// Return results 
UNWIND (CASE ws2Col WHEN [] THEN [null] ELSE ws2Col END) AS ws2a 
UNWIND (CASE ws3Col WHEN [] THEN [null] ELSE ws3Col END) AS ws3a 
UNWIND (CASE ws4Col WHEN [] THEN [null] ELSE ws4Col END) AS ws4a 
RETURN collect(distinct ws2a) AS match1, collect(distinct ws3a) AS match2, collect(distinct ws4a) AS match3 

答えて

0

ドキュメントにnullはリターンがnullなりますIN与えられたリストである場合は、テストThe in operator and null、よると:

ので、下記の式の戻りはnullになります。

RETURN null IN [1, 2, 3] 

╒═══════════════════╕ 
│"null IN [1, 2, 3]"│ 
╞═══════════════════╡ 
│null    │ 
└───────────────────┘ 

をその結果、式NOT(null IN [1, 2, 3])の戻り値もNULLになります。 w3は、それがリストの要素とはみなされませんnullとき:ある

AND NOT(w3 IS NULL OR w3 IN ws2Col) 

私はあなたがあなたのテストを変更するクエリを修正することができると思います。

+0

まだすべてを渡って空を返しますが、この時点でws2Colは保持されていますので、一歩近づいています。今実際に動作するコレクションのnullを処理する方法を見つける。 xxxx THEN ['none'] AS ...を次のように試してみました.... w3 IS NULL、w3はNULLではありません、w3Count = 0(コレクションの前に追加のWITH句でカウントを追加しようとしました) –

+0

@DaveClissold [coalesce関数](https://neo4j.com/docs/developer-manual/current/cypher/functions/scalar/#functions-coalesce)を見てください。私はそれがあなたを助けることができると思う。 –

+0

ありがとうございます。最後のオプションのマッチに到達すると、WHEREクエリ 'AND NOT(w4がNULLかws2Colのw4またはws3Colのw4)がヌルを返し、このポイントの直後で壊れた場合は、ws2Colとws3Colの値が削除されます単にws2Colとws3Colを返しますが、何も返しません。何かご意見は? –

関連する問題