2016-12-31 212 views
2

我有兩個Person節點。neo4j - MERGE創建重複節點

(p:Person {Name: 'Anthony'}) 
(p:Person {Name: 'Jason'}) 

有規定的關係是:

(p:Person)-[KNOWS]-(s:Skill) //s is dynamically entered 

要做到這一點,我使用的查詢:

MATCH (p:Person) 
WHERE p.Name='Anthony' 
MERGE(p)-[r:KNOWS{Weight:83}]-(x:Skill {Name:"WordPress"}) 

但是,如果我再次嘗試:

MATCH (p:Person) 
WHERE p.Name='Jason' 
MERGE(p)-[r:KNOWS{Weight:80}]-(x:Skill {Name:"WordPress"}) 

節點(s:Skill {Name: 'WordPress'})已創建再次

我明白MERGE將匹配整個圖案但我怎麼能保證這個查詢只創建Skill節點,如果它不存在?

回答

1

感謝有趣的博客文章:Here's a link

我發現,解決辦法是:

MATCH (p: Person) 
WHERE p.Name='Jason' 
MERGE (s:Skill {Name: 'Wordpress'}) 
CREATE UNIQUE (p)-[r:KNOWS {Weight:80}]-(s) 
RETURN (r) 

仍有意任何其他的答案! :)

3

請記住,您的MERGE正在尋找整個模式,包括您包括的價值。當你嘗試合併:KNOWS關係和一個不同的權重屬性時,它無法找到與這樣一個屬性的關係,所以它創建了整個模式。

該查詢的另一個問題是,正如您發現的那樣,創建模式時會創建一個新的Skill節點,即使圖中已經存在:Skill。正如你發現的那樣,在你融合模式之前,首先對技能進行合併是必要的。

至於處理新的屬性值,最好在完成模式(不包括MERGE中的屬性)之後完成。

例如:

MATCH (p: Person) 
WHERE p.Name='Jason' 
MERGE (s:Skill {Name: 'Wordpress'}) 
MERGE (p)-[r:KNOWS]-(s) 
SET r.Weight = 80 

同樣有用的,合併可以使用上創建和ON MATCH分別取決於MERGE是否匹配現有的圖案,或代替,以執行附加的操作(通常是一組操作)之後創建它。

+0

這很有趣!我不知道MERGE可以在同一個查詢中進行兩次。感謝你的回答! – Arjun

3

則有另一篇博客中解釋得非常好MERGE的行爲:http://graphaware.com/neo4j/2014/07/31/cypher-merge-explained.html

在一個側面節點和做培訓或幫助客戶,當我重複這往往:合併不會阻止重複,ONLY唯一性約束呢!

+0

謝謝你的鏈接,Christophe!我有另一個q(不知道我是否應該創建一個新線程),但是,我如何正式表示我的neo4j圖?在關係數據庫中,我們使用ER圖。是否建議在這裏使用ER圖或其他東西? – Arjun

+1

白板圖片是imo足夠好的圖表;-)否則有箭頭工具http://www.apcjones.com/arrows/# –

+0

謝謝!使用neo4j進行大學項目,並需要它來獲取文檔! :) – Arjun

1

在處理Neo4j節點和關係時,總是有習慣使用約束(唯一/斷言),以避免重複混亂,因爲更難清理它。 不知道這link會幫助你多少,但看看官方Neo4j網站提供的限制。

+0

非常感謝你@patilav!作爲neo4j的新手,我瞭解在創建和查詢我的數據存儲庫時遵循良好實踐的重要性,這要歸功於這些鏈接! – Arjun