2017-05-05 94 views
0

我需要根據關係返回一個節點及與其相關的所有節點。查詢的一個例子是這樣的:從Neo4j得到結果​​的最有效的方法

MATCH (n) where id(n)= {neo_id} 
OPTIONAL MATCH p=(n)-[:OWNS]->(q) 

它會更有效地獲取自身的節點「N」,然後獲得一個單獨的呼叫路徑,或者我應該做一個callthat回報「N」和'p'。

Addt。信息:我必須爲多重關係做到這一點,我注意到每次添加關係時,所有路徑之間的組合會導致性能下降。例如:

MATCH (n) where id(n)= {neo_id} 
OPTIONAL MATCH p=(n)-[:OWNS]->(q:Something) 
OPTIONAL MATCH o=(n)-[:USES]->(r:SomethingElse) 
. 
. 
. 
OPTIONAL MATCH l=(n)-[:LOCATED_IN]->(r:NthSomethingElse) 
RETURN n, p, o,..., l 

//Call 1 
MATCH (n) where id(n)= {neo_id} 
RETURN n 

//Call 2 
MATCH (n) where id(n)= {neo_id} 
OPTIONAL MATCH p=(n)-[:OWNS]->(q:Something) 
RETURN p 

//Call 3 
MATCH (n) where id(n)= {neo_id} 
OPTIONAL MATCH o=(n)-[:USES]->(r:SomethingElse) 
RETURN o 
. 
. 
. 
//Call nth 
MATCH (n) where id(n)= {neo_id} 
OPTIONAL MATCH l=(n)-[:LOCATED_IN]->(r:NthSomethingElse) 
RETURN l 

回答

2

如果你總是希望得到n(如果存在的話),即使它沒有關係,那麼你的第一個查詢確實是這樣做的唯一途徑。如果你不想這樣做,那麼將2個子句合併爲1可能對性能影響不大。

每當您添加另一個MATCH時,您會注意到減速的原因是因爲「笛卡爾產品」。即:如果MATCHOPTIONAL MATCH子句將「正常」生成N行數據,但同一查詢中的先前子句已生成M行數據,則實際生成的行數將爲M * N。所以,每個額外的MATCH都對數據行數有乘數效應。

根據您的使用情況,您可以通過對所有(或希望最多)MATCH子句的結果使用聚合來避免笛卡爾積,這可以將N變爲1(或其他較小數)。例如:

MATCH (n) where id(n)= {neo_id} 
OPTIONAL MATCH p=(n)-[:OWNS]->(:Something) 
WITH n, COLLECT(p) AS owns 
OPTIONAL MATCH o=(n)-[:USES]->(:SomethingElse) 
WITH n, owns, COLLECT(o) AS uses 
OPTIONAL MATCH l=(n)-[:LOCATED_IN]->(:NthSomethingElse) 
WITH n, owns, uses, COLLECT(l) AS located_in 
RETURN n, owns, uses, located_in; 
+0

完美!這很有道理。 –

相關問題