2016-11-15 14 views
0

當使用Cypher支架,以下查詢實際上將根據需要遍歷所有可能路徑。如何限制Cypher中的遍歷時間?

START n=node(0) 
MATCH (n)-[]-(p1:Person) 
RETURN n 

但我想要的是:停止遍歷一次一個子被發現,返回的結果告訴我它匹配。怎麼做?想給LIMIT超過MATCH?但據我知道LIMIT僅適用於RETURNMATCH

回答

2

如果使用LIMIT,Neo4j的將停止遍歷圖一旦找到匹配。

由於密碼是一種聲明性的查詢語言,查詢優化器將妥善處理LIMIT條款,也就是說,它會考慮模式匹配過程中限制。

讓我們設計一個實驗來證明這一點。示例性數據集:

CREATE 
    (p1:Person), 
    (p2:Person), 
    (p3:Person), 
    (p1)-[:KNOWS]->(p2), 
    (p1)-[:KNOWS]->(p3), 
    (p2)-[:KNOWS]->(p3) 

圖表看起來像這樣:

Example graph

首先,從查詢中刪除START子句,因爲它結合節點n到一個特定的ID,它是不是我們想要這個實驗。一般來說:START已被棄用,你應該儘可能避免使用它。

讓我們添加一個LIMIT 1約束,並使用PROFILE關鍵字分析查詢計劃:

PROFILE 
MATCH (n)-[]-(p1:Person) 
RETURN n 
LIMIT 1 

Query plan with LIMIT 1

取出LIMIT關鍵字,再分析查詢計劃:

PROFILE 
MATCH (n)-[]-(p1:Person) 
RETURN n 

Query plan without LIMIT

如您所見,帶有LIMIT 1約束條件的查詢計劃僅返回NodeByLabelScan操作中的單個行,其中包含2個數據庫匹配,而沒有約束的查詢計劃返回3行幷包含4個數據庫匹配。

更新:正如InverseFalcon的評論所建議的那樣,您還可以使用EXISTS函數,該函數將產生一個布爾值。但請注意,您仍需要LIMIT 1才能在結果中獲得一行(並避免不必要的數據庫命中)。

PROFILE 
MATCH (n) 
RETURN EXISTS((n)-[]-(:Person)) 
LIMIT 1 

enter image description here

+1

您還可能有興趣在exists()函數,如果本場比賽的唯一目的是要弄清楚,如果這樣的模式或路徑存在與否。 – InverseFalcon

+0

感謝@InverseFalcon,這非常有見地。我用'EXISTS'的解決方案更新了答案。有趣的是,你似乎仍然應該使用'LIMIT 1'。 「EXISTS」有沒有更優雅的方式? –

+1

這實際上取決於它在查詢中的使用方式。如果你正在匹配一個特定的節點(就像你原來的查詢中的節點(0))並且想知道它是否存在一個模式,那麼使用EXISTS()這個模式,它會給你一個true或false 。如果在與許多節點匹配時使用(如在此答案的查詢中,其中n與所有節點匹配),它將計算是否對所有行都使用該模式EXISTS()。請記住,LIMIT適用於整個結果集,它不是基於每行。 – InverseFalcon