2016-03-15 33 views
2

使用Neo4J 2.1.5這個密碼查詢很慢,有沒有優化?

數據:

2000人
目標:對於每個人,計算出總的朋友,朋友的朋友,朋友的朋友的朋友。
結果如下:
Person FullName |朋友總數| Friends-2 total | Friends-3 total |全球總數

MATCH (person:Person) 
WITH person 
OPTIONAL MATCH person-[:KNOWS]-(p2:Person) 
WITH person, count(p2) as f1 
OPTIONAL MATCH path = shortestPath(person-[:KNOWS*..2]-(f2:Person)) 
WHERE length(path) = 2 
WITH count(nodes(path)[-1]) AS f2, person, f1 
OPTIONAL MATCH path = shortestPath(person-[:KNOWS*..3]-(f3:Person)) 
WHERE length(path) = 3 
WITH count(nodes(path)[-1]) AS f3, person, f2, f1 
RETURN person._firstName + " " + person._lastName, f1, f2, f3, f1+f2+f3 AS total 

這些技巧是爲了避免錯誤的計算與cylic圖;這就是爲什麼我使用shortestPath

但是,此查詢持續很長時間:60秒! 有沒有可能的優化?

回答

1

[編輯]

這是否適合您?

MATCH (person:Person) 
OPTIONAL MATCH (person)-[:KNOWS]-(p1:Person) 
WITH person, COALESCE(COLLECT(p1),[]) AS p1s 
WITH person, CASE p1s WHEN [] THEN [NULL] ELSE p1s END AS p1s 
UNWIND p1s AS p1 
OPTIONAL MATCH (p1)-[:KNOWS]-(p2:Person) 
WHERE NOT ((p2 = person) OR (p2 IN p1s)) 
WITH person, p1s, COALESCE(COLLECT(DISTINCT p2),[]) AS p2s 
WITH person, p1s, CASE p2s WHEN [] THEN [NULL] ELSE p2s END AS p2s UNWIND p2s AS p2 
OPTIONAL MATCH (p2)-[:KNOWS]-(p3:Person) 
WHERE NOT ((p3 = person) OR (p3 IN p1s) OR (p3 IN p2s)) 
WITH person, 
    CASE p1s WHEN [NULL] THEN 0 ELSE SIZE(p1s) END AS f1, 
    CASE p2s WHEN [NULL] THEN 0 ELSE SIZE(p2s) END AS f2, 
    COUNT(DISTINCT p3) AS f3 
RETURN person.firstName + " " + person.lastName, f1, f2, f3, f1+f2+f3 AS total; 

每個朋友只計算一次。

下面是對一些比較模糊的策略的解釋。查詢必須用[NULL]替換空的p1sp2s集合,以便UNWIND不會中止查詢的其餘部分。然後,在計算收藏品的尺寸時,我們需要給[NULL]收藏品計數0

+0

f1是正確的,但它不會爲f2和f3返回好結果。 我期待51爲f2,但它返回73. – Mik378

+0

我不知道什麼可能是錯誤的在您的查詢... – Mik378

+0

添加一個'distinct':'COLLECT(distinct p2)'幫助,但它仍然是53 51. – Mik378