2017-03-07 96 views
0

我目前開始使用Neo4J,它是查詢語言密碼。 我有一個多重查詢,遵循相同的模式。優化Cypher查詢

我做一個SQL的數據庫和Neo4j的之間的一些比較。

在我的Neo4j Datababase我HABE一種類型的標籤(人)和一個類型的關係(友誼)。該人擁有個人身份,姓名,電子郵件,電話。 現在我想擁有這個朋友的第n個學位。我也想過濾出那些也是較低學位朋友的人。 例如,如果我想搜索朋友3度,我想過濾掉那些也是朋友第一和/或第二度的朋友。

這裏我的查詢類型:

MATCH (me:person {personID:'1'})-[:FRIENDSHIP*3]-(friends:person) 
WHERE NOT (me:person)-[:FRIENDSHIP]-(friends:person) 
AND NOT (me:person)-[:FRIENDSHIP*2]-(friends:person) 
RETURN COUNT(DISTINCT friends); 

我發現類似的東西的地方。

此查詢適用。

我的問題是,查詢的這種模式是非常慢,如果我搜索了更高程度的友誼和/或如果人數變得更加。

所以,我真的很感激它,如果somemone可以幫助我優化這個。

回答

1

如果你只是想處理的3深處,這應該返回是3度走,但不也小於3度走不同的節點:

MATCH (me:person {personID:'1'})-[:FRIENDSHIP]-(f1:person)-[:FRIENDSHIP]-(f2:person)-[:FRIENDSHIP]-(f3:person) 
RETURN apoc.coll.subtract(COLLECT(f3), COLLECT(f1) + COLLECT(f2) + me) AS result; 

上述查詢使用APOC功能apoc.coll.subtract到從結果中刪除不需要的節點。該函數還確保集合包含不同的元素。

下面的查詢就比較一般了,而且應該對於任何給定的深度合作(由剛更換*後的數字)。例如,該查詢將具有4的深度工作:

MATCH p=(me:person {personID:'1'})-[:FRIENDSHIP*4]-(:person) 
WITH NODES(p)[0..-1] AS priors, LAST(NODES(p)) AS candidate 
UNWIND priors AS prior 
RETURN apoc.coll.subtract(COLLECT(DISTINCT candidate), COLLECT(DISTINCT prior)) AS result; 
0

與Cypher支架的可變長度關係匹配的問題是,它在尋找到深度的所有可能路徑。當您感興趣的是某些深度的節點而不是通往它們的路徑時,這可能會導致不必要的性能問題。

APOC's path expander使用'NODE_GLOBAL'uniqueness是一種更有效的手段來匹配包含深度的節點。

當使用「NODE_GLOBAL」唯一性,節點永遠只能遍歷期間去過一次。因此,當我們將路徑擴展器的路徑擴展器minLevelmaxLevel設置爲相同時,結果是該級別的節點不在任何較低級別,這正是您試圖獲得的結果。

嘗試此查詢安裝APOC後:

MATCH (me:person {personID:'1'}) 
CALL apoc.path.expandConfig(me, {uniqueness:'NODE_GLOBAL', minLevel:4, maxLevel:4}) YIELD path 
// a single path for each node at depth 4 but not at any lower depth 
RETURN COUNT(path) 

當然,你想你的參數輸入(PERSONID,電平)當你得到機會。