2014-09-25 31 views
5

Mein Datenbankmodell hat Benutzer und MAC-Adressen. Ein Benutzer kann mehrere MAC-Adressen haben, aber ein MAC kann nur zu einem Benutzer gehören. Wenn ein Benutzer seinen MAC einstellt und dieser MAC bereits mit einem anderen Benutzer verknüpft ist, wird die bestehende Beziehung entfernt und eine neue Beziehung zwischen dem neuen Besitzer und dieser MAC erstellt. Mit anderen Worten, ein MAC bewegt sich zwischen Benutzern.Neo4j: MERGE erstellt doppelte Knoten

Dies ist eine bestimmte Instanz der Cypher Abfrage verwende ich MAC-Adressen zuweisen:

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) 

Die Abfrage in meinen Tests fein läuft, aber in der Produktion, es aus irgendeinem seltsamen Grund manchmal schafft Dupliziere MacAddress Knoten (und eine neue Beziehung zwischen dem Benutzer und jedem dieser Knoten). Das heißt, ein bestimmter Benutzer kann mehrere MacAddress Knoten mit demselben Value haben.

Ich kann sagen, dass sie verschiedene Knoten sind, weil sie unterschiedliche Knoten-IDs haben. Ich bin mir auch sicher, dass die Value s genau das gleiche sind, weil ich eine collect(distinct mac.Value) auf sie tun kann und das Ergebnis ist eine Sammlung mit einem Element. Die obige Abfrage ist die einzige im Code, die MacAddress Knoten erstellt.

Ich benutze Neo4j 2.1.2. Was ist denn hier los?

Danke, Jan

Antwort

4

Dies ist die Antwort, die ich von Neo4j Unterstützung (Hervorhebung von mir) bekam zurück:

ich von unserem Team ein Feedback schon bekommen, und es ist derzeit bekannt, dass diese in Abwesenheit von Zwang geschehen kann, . MERGE ist effektiv MATCH oder CREATE - und diese beiden Schritte werden innerhalb der Transaktion unabhängig voneinander ausgeführt. Bei der gleichzeitigen Ausführung und der Isolationsebene "Read Committed" gibt es eine Wettlaufbedingung zwischen den beiden.

Das Team hat eine Diskussion darüber geführt, wie eine höhere Garantie angesichts von Nebenläufigkeit bereitgestellt werden kann, und haben es als eine Feature-Anforderung zur Berücksichtigung notiert.

Inzwischen haben sie mir versichert, dass mit einer Einschränkung die Einzigartigkeit Sie suchen.

+2

Mehr ich benutze neo4j weniger Haare auf meinem Kopf .. –

5

Sind Sie sicher, dass dies die Summe der Anfragen ist Sie laufen? MERGE hat diese wirklich häufige Fallstrick, wo es alles verschmilzt, was Sie ihm geben. Also hier ist, was die Leute erwarten:

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 

So weit, so gut. Das erwarten wir. Jetzt schau dir das an:

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 

Warte, WTF ist hier passiert? Wir haben nur die gleiche MAC-Adresse erneut angegeben, warum wird ein Duplikat erstellt? Die documentation on MERGE gibt an, dass "MERGE vorhandene Muster nicht teilweise verwendet - es ist alles oder nichts. Wenn Teilübereinstimmungen erforderlich sind, kann dies durch Aufteilen eines Musters in mehrere MERGE-Klauseln erreicht werden". Also, wenn wir diesen Pfad MERGE ausführen, ist der gesamte Pfad nicht bereits vorhanden, es erstellt alles darin, einschließlich eines doppelten MAC-Adressknotens.

Es gibt häufig Fragen über doppelte Knoten, die von MERGE erstellt wurden, und 99 von 100, das ist was passiert.

+0

Ich weiß, dass MERGE entweder vollständig übereinstimmt oder nicht. Es ist, was es ist: eine MERGE eines Knotens mit einer 'MacAddress'-Bezeichnung und einer' Value'-Eigenschaft. Ich habe zwei 'MacAddress' Knoten mit genau dem gleichen' Wert'. –

Verwandte Themen