2016-10-28 14 views
1

假設我在Cypher支架指定標籤Person兩個唯一性約束:暗號MERGE有兩個唯一性約束

CREATE CONSTRAINT ON Person 
ASSERT name IS UNIQUE 
CREATE CONSTRAINT ON Person 
ASSERT id_number IS UNIQUE 

如果我運行下面的MERGE命令

MERGE (p:Person {name:"Alice", id_number=153}) 

的行爲是:

  • 如果有一個節點name Alice id_number 153,則返回
  • 如果與name愛麗絲XORid_number 153的一個節點,有一個錯誤,因爲我們不能創建一個新的節點,並保持兩者唯一性約束
  • 如果有節點既不是name Alice 也不是id_number 153,使用這些屬性創建新節點。

我想改變XOR行爲,讓我們做

  • 如果與name愛麗絲id_number 153的節點,則返回
  • 如果有節點既不是name Alice 也不是id_number 153,使用這些屬性創建新節點。

任何想法如何在Cypher中實現這一點?

回答

2

如果您有一個節點與name愛麗絲和另一個不同的節點與id_number 153會發生什麼?這是這種模式的核心哲學問題。設置的是,除了,你最親密的賭注是要手動調整MERGE邏輯,像這樣:

OPTIONAL MATCH (p:Person) 
WHERE p.name = 'Alice' or p.id_number = 153 
WITH COLLECT(p) AS ps 
WITH ps, CASE SIZE(ps) WHEN 0 THEN [True] ELSE [] END AS news 
UNWIND news AS new 
MERGE (q:Person {name: 'Alice', id_number:153}) 
WITH ps, COLLECT(q) AS qs 
WITH COALESCE(HEAD(ps), HEAD(qs)) AS p 

事實上你可能還需要在你的情況下唯一性約束;它們通常用於隨意取代常規索引,但如果您不得不擔心異步寫入(即使可以通過其他方式管理),它們也只是必需的。否則,只需要在查詢寫入時遵守規則,以便使用MERGE而不是CREATE,並且不要使用MERGE模式,這些模式應該是唯一的未綁定節點。