结合多个密码匹配语句的结果

时间:2016-10-22 05:51:45

标签: neo4j cypher

我正在尝试组合由三种匹配条件之一返回的任何节点:

(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

我很想知道是否有更优雅的解决方案。

1 个答案:

答案 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个关系,这也很好,并且会简化您的所有查询。