在Neo4j 2.0.0-M05我曾经做过
START n=node(*) MATCH n-[r?]-() WHERE ID(n) <> 0 AND ID(n) <> 1 DELETE n, r
删除除节点0和1之外的整个数据库。现在在Noe4j 2.0.0-RC1中我不能再使用问号了。但我必须使用像这样的OPTIONAL关键字:
START n=node(*) OPTIONAL MATCH n-[r]-() WHERE ID(n) <> 0 AND ID(n) <> 1 DELETE n, r
它匹配节点1(查询时数据库中不存在节点0)
neo4j-sh (?)$ START n=node(*) OPTIONAL MATCH n-[r]-() WHERE ID(n) <> 1 RETURN n, r;
+--------------------+
| n | r |
+--------------------+
| Node[1]{} | <null> |
+--------------------+
这当然不仅仅是针对这一个查询的问题,而是整个应用程序,我需要使用类似的查询。
在我看来,这引入了一个严重的设计缺陷。也许我的理由不在这里,而且由于问题1我也无法测试它。但OPTIONAL
关键字严重限制了查询的可能性。正如公告中所述,http://blog.neo4j.org/2013/11/neo4j-200-rc1-final-preparations.html OPTIONAL
可以与OUTER JOIN
进行比较。为了跟上这种从一个节点到另一个节点的跳跃,就像添加一个额外的连接一样。
之前
MATCH (a)-[x]-(b)-[y?]-(c) RETURN a, b, c
就像在做
SELECT a, b, c FROM ??
INNER JOIN x ON ??
LEFT OUTER JOIN y ON ??
(因为cypher没有转换为SQL所以存在问号)
但不是使用OPTIONAL关键字,您可以创建所有连接OUTER JOIN
或所有连接INNER JOIN
(不包含可选关键字)。没有混合的内部/外部联接查询,我的应用程序不起作用。对我来说,制作关系可选的 PER HOP 非常基础。所以要么我必须留在M06(支持问号的最新版本),要么尝试另一个数据库。
签名,
绝望的开发者。
答案 0 :(得分:2)
请提供一些样本数据和预期结果。我很确定您的两个查询可以使用可选匹配重写,如下所示。
你的WHERE子句奇怪地起作用的原因是因为直接跟随OPTIONAL MATCH的WHERE仅在OPTIONAL MATCH匹配时运行,作为该OPTIONAL MATCH的过滤器。所以在这种情况下,你发现n(id = 1),它不匹配n- [r] - (),因为n没有关系,然后它返回n。你需要首先过滤你的n,虽然我建议只使用MATCH而不是START(在这种情况下它没关系,但通常MATCH更好)。
对于#1,您需要改为执行此查询:
MATCH (n)
WHERE ID(n) <> 1
OPTIONAL MATCH n-[r]-()
RETURN n, r;
对于你的#2:
MATCH (a)-[x]-(b)
OPTIONAL MATCH (b)-[y]-(c)
RETURN a, b, c // c will be null if it doesn't exist