2016-10-22 92 views
0

結合的結果,我試圖通過三個匹配條件之一返回的任何節點結合:從多個暗號匹配語句

(p)-[:HAS_CAL]->(prodCal:ProdCal)-[:DELIVERS_TO]->(:Country {name: "USA"}) 
(p)-[:HAS_CAL]->(prodCal:ProdCal)-[:DELIVERS_TO]->(z:ZipCode {zipCode: delivZip}) 
(p)-[:HAS_CAL]->(prodCal:ProdCal)-[:DELIVERS_TO]->(zr:ZipRange) where zr.fromZip >= delivZip or zr.thruZip <= delivZip 

隨着那來自任何的那些比賽條件,我想回那麼任何結果執行另一場比賽。我猜,這意味着使用一個或的foreach放鬆身心的方式,如本:

unwind prodCals as prodCal 
match (prodCal)-[dd:DELIVERS]->(delivDay:Day) where dd.cutoff > (timestamp()/1000) 
return delivDay 

我已經試過幾件事情,但不能得到這個工作。最終結果應該是由match (prodCal)-[dd:DELIVERS]->(delivDay:Day) ...陳述中的每一個返回的一組delivDay

更新:

我似乎有一個可行的解決方案:

... 
with p, delivZip 
optional match (p)-[:HAS_CAL]->(prodCal1:ProdCal)-[:DELIVERS_TO]->(z:ZipCode {zipCode: delivZip}) 
with p, delivZip, prodCal1 
optional match (p)-[:HAS_CAL]->(prodCal2:ProdCal)-[:DELIVERS_TO]->(zr:ZipRange) where zr.fromZip >= delivZip or zr.thruZip <= delivZip 
with p, collect(prodCal1) + collect(prodCal2) as prodCals 
optional match(p)-[:HAS_CAL]->(prodCal3:ProdCal)-[:DELIVERS_TO]->(:Country {name: "USA"}) 
with collect(prodCal3) + prodCals as prodCals2 
unwind prodCals2 as cal 
match (cal)-[dd:DELIVERS]->(delivDay:Day) where dd.cutoff > (timestamp()/1000) 
return delivDay 

我很想知道是否有一個更優雅的解決方案,但。

回答

1
WITH p, delivZip 
MATCH (p) - [:HAS_CAL] -> (prodCal:ProdCal) 
WHERE (prodCal) - [:DELIVERS_TO] -> (:Country {name: "USA"}) 
OR (prodCal) -[:DELIVERS_TO] -> (:ZipCode {zipCode: delivZip}) 
OR ANY(path IN (prodCal) - [:DELIVERS_TO] -> (:ZipRange) WHERE delivZip >= LAST(NODES(path))['fromZip'] AND delivZip <= LAST(NODES(path))['thruZip']) 
WITH prodCal 
MATCH (prodCal)-[dd:DELIVERS]->(delivDay:Day) WHERE dd.cutoff > (TIMESTAMP()/1000) 
RETURN delivDay 

優雅是一種主觀的特性,當然,不過這避免了不必擔心COLLECT/UNWIND有心計,你會避免意外NULL結果誤差從OPTIONAL MATCH,並且它會順帶更好的性能。如果您可以選擇重構,那麼我會將這些:ZipRange節點替換爲與個人:ZipCode節點的關係;即使你必須建立100000個關係,這完全在容量之內,並且會簡化所有的查詢。

+0

感謝您的回答!我試圖理解'或任何(p IN(prodCal) - [:DELIVERS_TO] - >(:ZipRange)WHERE delivZip> = LAST(NODES(p))['fromZip'] AND delivZip <= LAST(NODES( p))['thruZip'])'better ...爲什麼在查看ZipRange節點的匹配時使用'OR ANY'?另外,爲什麼只檢查fromZip和thruZip列表中的最後一個節點('delivZip> = LAST(NODES(p))['fromZip']')? – novon

+0

啊。那麼括號裏面的語句是遍歷每一條匹配模式的路徑,然後對於每條路徑,檢查路徑'path'('LAST(NODES(path))'中的最後一個節點, ':ZipRange'節點)表示'delivZip'落入的範圍。如果該模式至少有一個路徑通過了這個過濾器,那麼ANY就會評估爲True,並且你的'prodCal'將被傳遞到結果行中。 (固定變量名稱以減少混淆)。 –

+0

哦,非常酷!關於爲'ZipRange'節點代表的每個郵政編碼創建':DELIVERS_TO'關係的另一點,是否不能有效地使'ProdCal'節點成爲超級節點?例如,我認爲從單個節點出來的80,000到100,000個關係是不好的做法?爲了擴大我的擔憂,這是一種經常發生的查詢模式,並且必須儘可能快。 – novon