2014-10-02 148 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