我正在尝试组合由三种匹配条件之一返回的任何节点:
(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
我已经尝试了几件事,但无法让它发挥作用。最终结果应该是每个delivDay
语句返回的一组match (prodCal)-[dd:DELIVERS]->(delivDay:Day) ...
。
更新
我似乎有一个有效的解决方案:
...
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
我很想知道是否有更优雅的解决方案。
答案 0 :(得分: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个关系,这也很好,并且会简化您的所有查询。