Neo4j cypher 2中的多个可选匹配子句

Neo4j cypher 2中的多个可选匹配子句,neo4j,pattern-matching,cypher,Neo4j,Pattern Matching,Cypher,我在从具有两条可选路径的图形中选择数据时遇到问题。假设节点A、B、C,其中A与B和C具有可选关系 如果我质疑 match (a:A) where a.xx = XX optional match (a:A)-->(b:B) return ... 或 一切正常 如果我将这两种方法结合起来: match (a:A) where a.xx = XX optional match (a:A)-->(b:B) optional match (a:A)-->(c:C) return

我在从具有两条可选路径的图形中选择数据时遇到问题。假设节点A、B、C,其中A与B和C具有可选关系

如果我质疑

match (a:A) where a.xx = XX optional match (a:A)-->(b:B) return ...

一切正常

如果我将这两种方法结合起来:

match (a:A) where a.xx = XX 
optional match (a:A)-->(b:B) 
optional match (a:A)-->(c:C) 
return ...
然后我只得到一个未知的错误(经过长时间的查询)

返回从a、b、c中选择属性,并使用限制来限制返回的数据量。不可能有多个可选匹配项吗

更新: 当我将查询更改为

match (a1:A) where a.xx = XX 
optional match (a2:A)-->(b:B) where a2.uid = a1.uid
optional match (a3:A)-->(c:C) where a3.uid = a1.uid
return ...
如果uid是唯一的索引id,则查询将返回所需的结果运行速度非常慢(如果uid是索引,则运行约60秒;如果uid具有唯一约束,则运行约40秒)
这个数据集不是我所说的庞大的:a 6500、b 86和c 90000个条目。

是的,您可以使用多个可选匹配项。例如,在console.neo4j.org中:

MATCH (n:Crew)-[r:KNOWS]-(m)
OPTIONAL
MATCH (n:Crew)-[r:KNOWS]-(b)
OPTIONAL
MATCH (n:Crew)-[r:KNOWS]-(c)
RETURN n,b,c

既然您已经匹配了一次
A
,为什么要重新匹配它

MATCH (a1:A) WHERE a.xx = XX 
OPTIONAL MATCH (a2:A)-->(b:B) WHERE a2.uid = a1.uid
OPTIONAL MATCH (a3:A)-->(c:C) WHERE a3.uid = a1.uid
可以更好地表达:

MATCH (a:A) WHERE a.xx = XX 
OPTIONAL MATCH (a)-->(b:B)
OPTIONAL MATCH (a)-->(c:C)
这看起来与您最初的示例非常接近,但没有理由让它表现糟糕。如果您可以在关系匹配项上放置一个类型,则性能会更好:

MATCH (a:A) WHERE a.xx = XX 
OPTIONAL MATCH (a)-[:REL]->(b:B)
OPTIONAL MATCH (a)-[:REL]->(c:C)
请注意,在将已绑定的节点带入可选的MATCH子句时,不需要重新标记这些节点

对于初始匹配使用的任何属性,都应该有索引:

CREATE INDEX ON :A(xx)
您可以在中尝试此操作,以查看其是否正常工作:

MATCH (n:Crew)
OPTIONAL MATCH (n)-[:KNOWS]-m
OPTIONAL MATCH (n)-[:LOVES]-t
RETURN n AS Neo,COLLECT(m) AS knows, COLLECT(t) AS loves

问题是这两个可选匹配创建了一个叉积,因此您希望在第二个匹配之前降低基数,即

create index on :A(xx);

MATCH (a:A) WHERE a.xx = XX 
OPTIONAL MATCH (a)-->(b:B) 
WITH a, collect(b) as b_nodes
OPTIONAL MATCH (a)-->(c:C) 
RETURN a, b_nodes, collect(c) as c_nodes`

显示错误时是否没有堆栈跟踪?如果您得到堆栈跟踪,请编辑您的问题并添加它。没有显示错误(我在通过neo4j控制台启动时也在控制台中检查了messages.log)。还使用最新版本(2.1.5)测试了相同的结果。查询运行了一段时间,吃掉了1个核心,然后在客户端中只出现“错误”就停止了。谢谢。这就是答案。我必须承认,我遗漏了关系规范。直到现在,由于我的懒惰,我还没有看到任何性能的下降。指定正确的关系后,查询将在约90毫秒内运行。谢谢你的解释。我重写了查询,最终不使用可选匹配。但我会记住首先使用最有选择性的条件。来自SQL,我没有这样做。
create index on :A(xx);

MATCH (a:A) WHERE a.xx = XX 
OPTIONAL MATCH (a)-->(b:B) 
WITH a, collect(b) as b_nodes
OPTIONAL MATCH (a)-->(c:C) 
RETURN a, b_nodes, collect(c) as c_nodes`