2014-09-04 38 views
1

我剛剛開始使用圖形數據庫和Neo4j。我創建了具有以下標籤的節點:人員,公司,城市,技能,它們之間有一個或多個關係。Cypher查詢性能和結構

我想做一個密碼查詢找到一個人節點(通過節點ID),然後我想找到所有的技能,公司等與此人相關。這是迄今爲止我的查詢:

MATCH (person:Person) 
WHERE ID (person) = 123 
WITH person LIMIT 1 
OPTIONAL MATCH (p:Person) - [:HAS_SKILL] -> (skill:Skill) 
WHERE ID (p) = 123 
WITH person, skill ORDER BY skill.name ASC 
OPTIONAL MATCH (p:Person) - [:WORKED_AT] -> (company:Company) 
WHERE ID (p) = 123 
WITH person, skill, company ORDER BY company.name ASC 
OPTIONAL MATCH (p:Person) - [:LIVES_IN] -> (city:City) 
WHERE ID (p) = 123 
WITH person 
, collect(DISTINCT skill) as skills 
, collect(DISTINCT company) as companies 
, city LIMIT 1 
RETURN person, skills, companies, city 

我擔心這是不是一個真正的最佳查詢和它看起來會很慢,如果/當我們可以說幾百萬的節點。有人能告訴我一個更好的方式來構建這種查詢嗎?我應該把它分成幾個更小的查詢嗎?

回答

2

我認爲首先是你不需要繼續查詢person對象,但我不確定這會影響性能,因爲person變量已經綁定了。這降低了您的查詢:

MATCH (person:Person) 
WHERE ID (person) = 123 
WITH person 
OPTIONAL MATCH (person) - [:HAS_SKILL] -> (skill:Skill) 
WITH person, skill ORDER BY skill.name ASC 
OPTIONAL MATCH (person) - [:WORKED_AT] -> (company:Company) 
WITH person, skill, company ORDER BY company.name ASC 
OPTIONAL MATCH (person) - [:LIVES_IN] -> (city:City) 
WITH person 
, collect(DISTINCT skill) as skills 
, collect(DISTINCT company) as companies 
, city LIMIT 1 
RETURN person, skills, companies, city 

你也不需要繼續使用WITH因爲你可以有多個匹配語句,但現在我已刪除了您的訂單聲明:

MATCH (person:Person) 
WHERE ID (person) = 123 
OPTIONAL MATCH (person) - [:HAS_SKILL] -> (skill:Skill) 
OPTIONAL MATCH (person) - [:WORKED_AT] -> (company:Company) 
OPTIONAL MATCH (person) - [:LIVES_IN] -> (city:City) 
RETURN person 
, collect(DISTINCT skill) as skills 
, collect(DISTINCT company) as companies 
, city LIMIT 1 

我相信那麼你可以訂購更多類似這樣的,但你會與一個奇怪的排序順序!:

MATCH (person:Person) 
WHERE ID (person) = 123 
OPTIONAL MATCH (person) - [:HAS_SKILL] -> (skill:Skill) 
OPTIONAL MATCH (person) - [:WORKED_AT] -> (company:Company) 
OPTIONAL MATCH (person) - [:LIVES_IN] -> (city:City) 
WITH DISTINCT person, skill, company, city 
ORDER BY skill.name, company.name 
RETURN person 
, collect(DISTINCT skill) as skills 
, collect(DISTINCT company) as companies 
, city LIMIT 1 

無論是任何更好的性能,你必須考到結束。如果你想要施加限制或聚合,你需要像原來一樣使用WITH語句。

只是馬克李約瑟在優化想起這個blog post,並不直接相關,但包含了一些規則,值得回頭參考:

  1. 使用參數時,您可以。
  2. 避免笛卡爾產品,當他們不需要獲取您需要的數據。
  3. 避免使用WHERE子句中的模式
  4. 以最低基數標識符(理想情況下爲1)開始您的MATCH模式並向外擴展。
  5. 分開你的MATCH模式,爲每個模式做最小的擴展。爲每個模式添加1個新標識符。
  6. 呼喚Wes!