2014-07-06 108 views
3

如何有效地過濾連接到某組節點的所有節點?過濾與密碼中特定節點相關的節點

我有這個現在:

MATCH (:City { Id: 10 })<-[:LIVES_IN]-(p:Person), 
p-[:KNOWS]->(:Person { Name: 'John' }), 
p-[:KNOWS]->(:Person { Name: 'Mark' }), 
p-[:KNOWS]->(:Person { Name: 'Jane' }), 
p-[:KNOWS]->(:Person { Name: 'Mary' }) 
RETURN p 

這我想要做什麼,但它是非常緩慢的。大約需要900毫秒的數據庫。標記爲人員的500個節點。

我要解決的問題是更大

MATCH (:City { Id: 10 })<-[:LIVES_IN]-(p:Person)-[:HAS_ITEM]->(i:Item), 
p-[:KNOWS]->(:Person { Name: 'John' }), 
p-[:KNOWS]->(:Person { Name: 'Mark' }), 
p-[:KNOWS]->(:Person { Name: 'Jane' }), 
p-[:KNOWS]->(:Person { Name: 'Mary' }) 
RETURN i, count(p) 

該查詢發現,有一個項目,並對每個項目,它返回擁有該項目,也知道某些人所有的人的數量的人。這個查詢永遠不會結束(或者我沒有等待足夠長的時間)。

當我刪除「知道某人的部分」時,查詢在大約400ms內完成。

MATCH (:City { Id: 10 })<-[:LIVES_IN]-(p:Person)-[:HAS_ITEM]->(i:Item), 
RETURN i, count(p) 

我在做什麼錯?

回答

3

嘗試對其進行重新排序以儘量減少一次搜索的結果數量。像這樣的東西 - 如果知道羣體比城市中居住的人數和擁有物品的人數還要少,那麼這可能會更好(如果有物品的人很低,可以交換它):

MATCH (p:Person)-[:KNOWS]->(:Person { Name: 'John' }) // start with john's friends 
WITH p 
MATCH (:City { Id: 10 })<-[:LIVES_IN]-(p)-[:HAS_ITEM]->(i:Item) // only friends that live in city 10 and have the item... 
WITH p, i 
MATCH p-[:KNOWS]->(:Person { Name: 'Mark' }) 
WITH p, i 
MATCH p-[:KNOWS]->(:Person { Name: 'Jane' }) 
WITH p, i 
MATCH p-[:KNOWS]->(:Person { Name: 'Mary' }) 
RETURN i, count(p) 

此外,還要確保你有:Person(Name)指數和:City(Id)

+0

With語句的伎倆。把'MATCH(:City {Id:10})< - [:LIVES_IN] - (p) - [:HAS_ITEM] - >(i:Item)'作爲最後的語句,可以提供更好的性能。我認爲這是因爲有很多物品與人相連,並在穿越物品之前減少了人數。查詢現在爲100ms以下,並且在添加更多'p - [:KNOWS] - >(某人)'過濾器時,執行時間會更多。謝謝! – dominiktomicevic