【问题标题】:multiple OPTIONAL MATCH clauses in cypher 2密码 2 中的多个 OPTIONAL MATCH 子句
【发布时间】:2014-10-21 07:16:23
【问题描述】:

我在从具有 2 个可选路径的图表中选择数据时遇到问题。假设节点 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)-->(c:C) return ...

一切都按预期进行。

如果我结合2:

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

然后我只得到(经过长时间的查询)一个未知错误。

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 个条目。

【问题讨论】:

  • 显示错误时是否没有堆栈跟踪?如果您有堆栈跟踪,请编辑您的问题并添加它。
  • 没有错误出现(当通过neo4j控制台启动时,我也在控制台中检查了messages.log)。还使用最新版本 (2.1.5) 进行了测试,结果相同。查询运行了一段时间,吃掉了 1 个核心,然后在客户端中只出现“错误”而停止..

标签: neo4j pattern-matching cypher


【解决方案1】:

鉴于你已经匹配了一次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)

请注意,在将已经绑定的节点带入 OPTIONAL MATCH 子句时,您不需要重新标记它们。

您应该对用于初始匹配的任何属性都有一个索引:

CREATE INDEX ON :A(xx)

您可以在console 中尝试此操作以查看它是否有效:

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

【讨论】:

  • 谢谢。这就是答案。我必须承认,我忽略了关系规范。到目前为止,由于我的懒惰,我没有看到任何性能下降。指定正确的关系后,查询将在 ~90 ms 内运行。谢谢
【解决方案2】:

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

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`

【讨论】:

  • 感谢您的解释。我重写了查询,毕竟不使用可选匹配。但我会记住首先使用最具选择性的条件。来自 SQL,我没有这样做。
【解决方案3】:

是的,您可以使用多个可选匹配。例如,在 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

【讨论】:

    猜你喜欢
    • 2015-11-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多