简体   繁体   English

密码2中的多个OPTIONAL MATCH子句

[英]multiple OPTIONAL MATCH clauses in cypher 2

I have a problem selecting data from a graph with 2 optional paths. 我在使用2个可选路径从图表中选择数据时遇到问题。 Assume nodes A, B, C where A has optional relations to B and C. 假设节点A,B,C,其中A与B和C具有可选关系。

If I query 如果我查询

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

or 要么

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

everything works as expected. 一切都按预期工作。

If I combine the 2: 如果我结合2:

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

then I only get (after a long querying time) an unknown error. 然后我只得到(经过长时间的查询时间)一个未知的错误。

The return selects attributes from a,b,c and uses a limit to restrict the amount of data returned. 返回从a,b,c中选择属性,并使用限制来限制返回的数据量。 Is it not possible to have more than one optional match? 是否不可能有多个可选匹配?

Update: When I change the query to 更新:当我将查询更改为

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 ...

with uid being an unique indexed id then the query returns the required result. 如果uid是唯一的索引id,则查询返回所需的结果。 But it runs very slowly (~60 seconds if uid is an index and ~40s if uid has a unique constraint) The dataset is not something I would call huge: a 6500 , b 86 and c 90000 entries. 它的运行速度非常慢(如果uid是索引,则约为60秒;如果uid具有唯一约束,则约为40秒)数据集不是我称之为巨大的数据集:6500,b 86和c 90000条目。

given you have already matched A once, why are you rematching it? 鉴于你已经匹配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

Could be better expressed: 可以更好地表达:

MATCH (a:A) WHERE a.xx = XX 
OPTIONAL MATCH (a)-->(b:B)
OPTIONAL MATCH (a)-->(c:C)

That looks dangerously close to your initial example, but there is no reason for it to perform badly. 这看起来非常接近你最初的例子,但没有理由让它表现糟糕。 It would perform better if you could put a type on the relationship matches: 如果你可以在关系匹配上放置一个类型,它会表现得更好:

MATCH (a:A) WHERE a.xx = XX 
OPTIONAL MATCH (a)-[:REL]->(b:B)
OPTIONAL MATCH (a)-[:REL]->(c:C)

Please note that you do not need to relabel the already bound nodes when carrying them through into the OPTIONAL MATCH clauses. 请注意,在将已经绑定的节点传送到OPTIONAL MATCH子句中时,您不需要重新标记它们。

You should have an index on whichever property you are using for the initial match: 对于初始匹配,您应该使用任何属性的索引:

CREATE INDEX ON :A(xx)

You can try this in the console to see it working: 您可以在控制台中尝试此操作以查看它是否正常工作:

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

the problem is that the two optional matches create a cross product , so you'd want to get the cardinality down befor the second one, ie 问题是两个可选匹配创建了一个交叉产品 ,所以你想要将第二个基数降低,即

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`

Yes, you can use multiple optional match. 是的,您可以使用多个可选匹配。 For example, in console.neo4j.org: 例如,在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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM