2014-09-25 42 views
5

我的數據庫模型有用戶和MAC地址。一個用戶可以有多個MAC地址,但一個MAC只能屬於一個用戶。如果某個用戶設置了自己的MAC,並且該MAC已經鏈接到另一個用戶,則現有關係將被刪除,並在新所有者與該MAC之間建立新的關係。換句話說,MAC在用戶之間移動。Neo4j:MERGE會創建重複節點

這是我使用指定的MAC地址Cypher支架查詢的特定實例:

MATCH (new:User { Id: 2 }) 
MERGE (mac:MacAddress { Value: "D857EFEF1CF6" }) 
WITH new, mac 
OPTIONAL MATCH()-[oldr:MAC_ADDRESS]->(mac) 
DELETE oldr 
MERGE (new)-[:MAC_ADDRESS]->(mac) 

查詢運行在我的測試正常,但在生產中,它有時創建一些奇怪的原因重複MacAddress節點(以及用戶和每個這些節點之間的新關係)。也就是說,一個特定的用戶可以有多個MacAddress節點,並且具有相同的Value

我可以告訴他們是不同的節點,因爲他們有不同的節點ID。我也確定Value完全一樣,因爲我可以在它們上面做一個collect(distinct mac.Value),結果是一個元素的集合。上面的查詢是創建MacAddress節點的代碼中唯一的一個。

我正在使用Neo4j 2.1.2。這裏發生了什麼?

感謝, 揚

回答

4

這是我從的Neo4j的支持(重點煤礦)回來的響應:

我從我們團隊的一些反饋已經和它目前已知這可以在沒有約束的發生。 MERGE實際上是MATCH或CREATE - 並且這兩個步驟在事務內獨立運行。考慮到併發執行和「讀取提交」隔離級別,兩者之間存在競爭條件。

該團隊已經就如何在面臨併發時提供更高的保證問題做了一些討論,並且確實已將其作爲特性請求予以考慮。

同時,他們已經向我保證,使用約束將提供您正在尋找的唯一性

+2

更多我使用neo4j更少的頭髮留在我的頭上.. – 2017-02-02 12:08:25

5

你確定這是你正在運行的查詢的全部? MERGE有這個真正常見的陷阱,它融合了你給它的所有東西。所以這是人們所期望的:

neo4j-sh (?)$ MERGE (mac:MacAddress { Value: "D857EFEF1CF6" }); 
+-------------------+ 
| No data returned. | 
+-------------------+ 
Nodes created: 1 
Properties set: 1 
Labels added: 1 
1650 ms 
neo4j-sh (?)$ MERGE (mac:MacAddress { Value: "D857EFEF1CF6" }); 
+--------------------------------------------+ 
| No data returned, and nothing was changed. | 
+--------------------------------------------+ 
17 ms 
neo4j-sh (?)$ match (mac:MacAddress { Value: "D857EFEF1CF6" }) return count(mac); 
+------------+ 
| count(mac) | 
+------------+ 
| 1   | 
+------------+ 
1 row 
200 ms 

到目前爲止,這麼好。這就是我們所期望的。現在看這個:

neo4j-sh (?)$ MERGE (mac:MacAddress { Value: "D857EFEF1CF6" })-[r:foo]->(b:SomeNode {label: "Foo!"}); 
+-------------------+ 
| No data returned. | 
+-------------------+ 
Nodes created: 2 
Relationships created: 1 
Properties set: 2 
Labels added: 2 
178 ms 
neo4j-sh (?)$ match (mac:MacAddress { Value: "D857EFEF1CF6" }) return count(mac);      
+------------+ 
| count(mac) | 
+------------+ 
| 2   | 
+------------+ 
1 row 
2 ms 

等待,跆拳道發生在這裏?我們只指定了相同的MAC地址,爲什麼重複創建?

documentation on MERGE指定「MERGE不會部分使用現有模式 - 全部或全部不需要,如果需要部分匹配,可以通過將模式分成多個MERGE子句來完成。因此,當我們運行此路徑MERGE時,整個路徑不存在,它將創建所有內容,包括重複的mac地址節點。

經常有關於由MERGE創建的重複節點的問題,以及100次中的99次,這就是發生了什麼事情。

+0

我知道MERGE要麼完全匹配,要麼沒有。它就是這樣的:具有'MacAddress'標籤和'Value'屬性的節點的MERGE。我有兩個「MacAddress」節點,它們具有完全相同的「值」。 – 2014-09-25 20:54:38