2014-10-02 149 views
2

我想从几条不同路径中提取并合并数据,这些路径在开始时共享一条路径,而不是所有路径都可能存在。例如,我想要做这样的事情:在多个MATCH UNION查询中重复使用路径cypher neo4j

MATCH (:Complex)-[:PATH]->(s:Somewhere)-[:FETCHING]->(data) 
    RETURN data.attribute 
UNION ALL 
MATCH (s)-[:OPTIONAL]->(o:OtherData) 
    RETURN o.attribute; 

这样它就不会回溯至s。尽管我实际上做不到这一点,因为UNION分离查询,而第二部分中的[(s) - [:OPTIONAL]将匹配传出OPTIONAL关系的任何内容; s是一个松散的手柄。

是否有这样做不是重复路径的更好的办法:

MATCH (:Complex)-[:PATH]->(s:Somewhere)-[:FETCHING]->(data) 
    RETURN data.attribute 
UNION ALL 
MATCH (:Complex)-[:PATH]->(s:Somewhere)-[:OPTIONAL]->(o:OtherData) 
    RETURN o.attribute; 

我使用WITH做了一些尝试,但他们都要么导致查询返回什么,如果任何部分失败,我也可以不要让他们排成一列,而是得到具有冗余数据的行,或者(有多个嵌套的WITHs,我不确定关于范围的确定)只是获取所有内容。

回答

1

你看过可选匹配的语义吗?所以你可以匹配s,超越s和你的可选组件。例如:

MATCH (:Complex)-[:PATH]->(s:Somewhere) 
MATCH (s)-[:FETCHING]->(data) 
OPTIONAL MATCH (s)-[:OPTIONAL]->(otherData) 
RETURN data.attribute, otherData.attribute 

对不起,我错过了单列的重要性,它真的很重要吗?

您可以收集vaues成一个单一的集合

MATCH (:Complex)-[:PATH]->(s:Somewhere) 
MATCH (s)-[:FETCHING]->(data) 
OPTIONAL MATCH (s)-[:OPTIONAL]->(otherData) 
RETURN [data.attribute] + COLLECT(otherData.attribute) 

,但不会对单个列这项工作:

MATCH (:Complex)-[:PATH]->(s:Somewhere) 
MATCH (s)-[:FETCHING]->(data) 
OPTIONAL MATCH (s)-[:OPTIONAL]->(otherData) 
WITH [data.attribute] + COLLECT(otherData.attribute) as col 
RETURN UNWIND col AS val 
+0

这不排队的事情成一列。如果只有一个数据匹配,并且其他数据匹配很多,那么我会在右边的每个其他Data.attribute的左边获得一个具有相同data.attribute的2列结果。这两种数据的类型是相同的,所以我试图获得单个列,就像我的示例查询给出的那样。 – 2014-10-02 22:55:45

+0

您的语法不完全正常,但我可以让它适用于: ' MATCH(:Complex) - [:PATH] - >(s:Somewhere) MATCH(s) - [:FETCHING] - >(data) 可选MATCH(s) - [:可选] - >(otherData) WITH [data.attribute] + COLLECT(otherData.attribute)as col UNWIND col AS val RETURN val; ' 它给出了需要消除的空值,但并不差。最后,我认为UNION是要走的路,能够保存引用并拥有可引用它们的内部作用域会很好,所以我可以进行顶级匹配,然后有一个内部查询在UNION的每个部分都引用它。谢谢! – 2014-10-03 16:17:43

+0

太棒了,但我不明白你的NULL值是从哪里来的 - 我假设以上都是理论上的查询,但我不认为应该有任何空值。但是,如果有,您可以使用过滤器来摆脱它们。 http://docs.neo4j.org/chunked/stable/query-functions-collection.html#functions-filter – JohnMark13 2014-10-03 16:37:00