当OPTIONAL MATCH为空时,如何编写cypher语句来组合节点?

时间:2017-05-09 18:09:17

标签: neo4j cypher match optional

背景

大家好,我目前正在尝试编写一个cypher语句,允许我从起点找到地图上的一组路径。 我希望我的搜索结果始终返回5个节点内的连接街道。或者,如果附近有医院,我希望我的搜索模式也能指示附近的医院。

主要问题

因为当前街道附近的医院并不总是,有时我的可选匹配搜索模式会返回为空。这是我目前使用的密码声明:

MATCH path=(a:Street {id: 123})-[:CONNECTED_TO*..5]-(b:Street)
OPTIONAL MATCH optionalPath=(b)-[:CONNECTED_TO]->(hospital:Hospital)
WHERE ALL (x IN nodes(path) WHERE (x:Street))
WITH DISTINCT nodes(path) + nodes(optionalPath) as n
UNWIND n as nodes
RETURN DISTINCT nodes;

但是,此语法仅在 optionalPath 包含节点时才有效。如果它没有,则语句nodes(path) + nodes(optionalPath)是一个添加null的操作,我没有记录。即使nodes(path)术语确实包含节点,也是如此。

解决此问题的最佳方法是什么?

2 个答案:

答案 0 :(得分:2)

您可以使用COALESCENULL替换为其他值。例如:

MATCH path=(:Street {id: 123})-[:CONNECTED_TO*..5]-(b:Street)
WHERE ALL (x IN nodes(path) WHERE x:Street)
OPTIONAL MATCH optionalPath=(b)-[:CONNECTED_TO]->(hospital:Hospital)
WITH nodes(path) + COALESCE(nodes(optionalPath), []) as n
UNWIND n as nodes
RETURN DISTINCT nodes;

我还做了一些其他改进:

  1. WHERE子句在第一个MATCH之后立即上移。这会立即消除不需要的path值。您的原始查询将获得所有path值(甚至是不需要的值),并始终执行第二个MATCH查询,并且之后只消除不需要的路径。 (但是,实际上并不清楚您是否甚至需要WHERE子句;例如,如果CONNECTED_TO关系仅用于Street个节点之间。)

    < / LI>
  2. DISTINCT子句中的WITH会阻止重复的n个集合,但内部集合可能有重复的路径。这可能不是你想要的。

答案 1 :(得分:0)

您似乎并不真正想要这条路,只需5步内的所有街道节点,再加上任何连接的医院。所以我会简化你的查询,然后将3列压缩为1。

MATCH (a:Street {id: 123})-[:CONNECTED_TO*..5]-(b:Street)
OPTIONAL MATCH (b)-[:CONNECTED_TO]->(hospital:Hospital)
WITH collect(a) + collect(b) + collect(hospital) as n
UNWIND n as nodez
RETURN DISTINCT nodez;

如果Streets可以间接连接(介于两者之间的医院),那么我可以像这样调整

MATCH (a:Street {id: 123})-[:CONNECTED_TO]-(b:Street)
WITH a as nodez, b as a
MATCH (a)-[:CONNECTED_TO]-(b:Street)
WITH nodez+collect(b) as nodez, b as a
MATCH (a)-[:CONNECTED_TO]-(b:Street)
WITH nodez+collect(b) as nodez, b as a
MATCH (a)-[:CONNECTED_TO]-(b:Street)
WITH nodez+collect(b) as nodez, b as a
MATCH (a)-[:CONNECTED_TO]-(b:Street)
WITH nodez+collect(b) as nodez, b as a
OPTIONAL MATCH (b)-[:CONNECTED_TO]->(hospital:Hospital)
WITH nodez + collect(hospital) as n
UNWIND n as nodez
RETURN DISTINCT nodez;

它有点冗长,但只是准确地说出你想要的东西(并且还将起始节点添加到医院检查清单)