2017-06-29 3 views
1

Ich versuche, einige Daten in Neo4J zu laden. Ich habe einen Person Knoten, der bereits eingerichtet ist. Jetzt muss dieser Knoten eine email Eigenschaft haben, die ein Array (oder eine Sammlung) sein sollte. Grundsätzlich ist die email Eigenschaft muss mehrere Werte haben, wie -Wie mehrere Werte zu bestehenden Knoten mit Cypher in Neo4J hinzugefügt werden

email: ["[email protected]", "[email protected]"] 

Ich bin gekommen, über ähnliche Fragen hier aber alle Antworten zeigen auf mehrere Eigenschaft festlegen an dem Zeitwert der Knoten selbst erstellt wird. Wie diese Abfrage aus this Antwort -

CREATE (e:Employee { name:"Sam",languages: ["C", "C#"]}) 
RETURN e 

Aber das Problem in meinem Fall ist, dass Person Knoten bereits erstellt wird, und ich brauche jetzt die email Eigenschaft auf sie einzustellen.

Dies ist eine kleine Teilmenge der Daten, die ich laden müssen -

Personid|email 
933|[email protected] 
933|[email protected] 
933|[email protected] 
1129|[email protected] 
1129|[email protected] 
1129|[email protected] 
4194|[email protected] 
4194|[email protected] 

Auch werden die Daten aus einer CSV kommen mit Tausenden von Zeilen-Datei, so meine Frage generisch sein muss, kann ich‘ t Legen Sie die Eigenschaften für jeden einzelnen Knoten Person fest.

Als ich die Erstellung der E-Mail-Eigenschaft mit dieser Untergruppe, mein erster Versuch testet war -

MATCH (n:TESTPERSON{id:933}) 
SET n.email = "[email protected]" 
RETURN n 

MATCH (n:TESTPERSON{id:933}) 
SET n.email = "[email protected]" 
RETURN n 

Als ich dachte, dies überschreibt nur die email Eigenschaft auf den Wert in den jüngsten Abfrage.

Nachdem hier bei den Antworten zu suchen und auf dem Cypher docs, fand ich heraus, dass Neo4j Ihnen einen Array/Sammlung (mehrere Werte des gleichen Typs) als Eigenschaft Wert setzen, und ich habe dann versucht, diese -

// CREATE test node 
CREATE (n:TESTPERSON{id:933}) 
RETURN n 

// at this time, this node does not have any `email` property, so setup 
// email as an array with one string value 
MATCH (n:TESTPERSON{id:933}) 
SET n.email = ["[email protected]"] 
RETURN n 


// Now, using +=, I can append to the array of strings 
MATCH (n:TESTPERSON{id:933}) 
SET n.email = n.email + "[email protected]" 
RETURN n 

// add a third value to array 
MATCH (n:TESTPERSON{id:933}) 
SET n.email = n.email + "[email protected]" 
RETURN n 

Hier ist das Ergebnis - enter image description here

Wie Sie sehen können, die email Eigenschaft hat jetzt mehrere Werte.

Aber das Problem ist, dass, da meine CSV-Datei Tausende von Zeilen hat, brauche ich eine generische Abfrage, um dies zu tun.

Ich dachte an eine CASE Erklärung gemäß der Dokumentation mit here und versuchte, diese -

MATCH (n:TESTPERSON {id:933}) 
CASE 
WHEN n.email IS NULL THEN SET n.email = [ "[email protected]"] 
ELSE SET n.email = n.email + "[email protected]" 
RETURN n 

Aber das wirft nur den Fehler - mismatched input CASE expecting ;.

Ich habe gehofft, ich diese Abfrage als eine generische Art und Weise nutzen könnte für meine CSV-Datei wie diese -

LOAD CSV WITH HEADERS FROM 'FILEURL' AS line FIELDTERMINATOR `|` 
MATCH (n:TESTPERSON {id:toInt(line.Personid)}) 
CASE 
WHEN n.email IS NULL THEN SET n.email = [line.email] 
ELSE SET n.email = n.email + line.email 

Aber ich weiß nicht einmal, ob das funktionieren würde, auch wenn die CASE Fehler behoben sind.

Ich bin wirklich ratlos und würde jede Hilfe zu schätzen wissen. Danke.

Antwort

2

Sie können COALESCE() verwenden, um einen Standardwert zu verwenden, wenn der Wert, den Sie erhalten möchten, null ist. Man könnte es wie folgt verwenden:

... SET n.email = COALESCE(n.email, []) + "[email protected]" ...

Jedes Mal, wenn Sie ein Array von Werten als Knoten Eigenschaft sind einstellen, ist es eine gute Idee zu prüfen, ob Sie stattdessen dieser als separater Knoten mit Beziehungen zu dem ursprünglichen Modell könnte Knoten.

In diesem Fall: E-Mail-Knoten mit einer Beziehung zu Ihren: TESTPERSON-Knoten, mit einem: E-Mail-Knoten pro E-Mail und mehreren Beziehungen von: TESTPERSON zu mehreren: E-Mails.

Ein Vorteil hier ist, dass Sie in der Lage sind, Eindeutigkeitseinschränkungen zu unterstützen, wenn Sie sicherstellen möchten, gibt es nur eine: E-Mail im System, und Sie könnten schnell eine Person per E-Mail nachschlagen, wenn Sie eine haben Index oder eindeutige Einschränkung, da die Abfrage den Index verwenden würde, um nach der: E-Mail zu suchen, und von dort wird nur eine Beziehung zum Eigentümer der E-Mail durchlaufen.

Wenn Sie Werte in einer Auflistung auf einem Knoten haben, können Sie eine Indexsuche nicht auf einen Wert in der Auflistung anwenden, sodass Ihr aktuelles Modell eine Person nicht schnell nach ihrer E-Mail suchen kann.

+0

Danke! Das hat perfekt funktioniert.Hier ist die Abfrage, die ich ausgeführt habe - 'CSV mit Kopfzeilen laden von 'fileURL" AS Zeile FIELDTERMINATOR' | ' MATCH (n: TESTPR. {ID: toInt (line.Personid)}) SET n.email = COALESCE (n.email, []) + line.email' –

0

diese Lösung Versuchen MERGE mit:

LOAD CSV WITH HEADERS FROM 'file:///p.csv' AS line FIELDTERMINATOR '|' 
MERGE (p:Person {id:toInteger(line.Personid)}) 
ON CREATE SET p.mail = line.email 
ON MATCH SET p.mail = p.mail + '-' + line.email 

Der MERGE Befehl kümmert sich um den doppelten Knoten, und dann sind wir die Eigenschaften nur einstellen, wenn der Knoten mit ON CREATE SET erstellt wird, und wenn der Knoten bereits In der Datenbank (z. B. ON MATCH SET) fügen wir der Unterkunft die E-Mail-Adresse hinzu.

Hoffe, dass hilft.

Das ist mein Ergebnis in Neo4j: enter image description here

+0

Hallo, danke für die Antwort !! Mein Code hat bereits den 'Person' Knoten Setup, also denke ich, dass diese Zeile überhaupt nicht ausgeführt wird -' ON CREATE SET p.mail = line.email'. Das heißt, "p.mail" wird "null" sein und wenn es die "ON MATCH SET" -Klausel erreicht, wird der Code 'ON MATCH SET p.mail = p.mail + '-' + line.email'' ergeben null, weil zu diesem Zeitpunkt "p.mail" immer noch "null" ist, und das Hinzufügen von irgendetwas zu "null" wird "null" zurückgeben. Auch im Code in Ihrem Screenshot ist 'email' eine String-Eigenschaft mit Strings, die mit' -' verkettet sind, während ich stattdessen 'email' brauche, um ein Array von Strings zu sein. Gedanken? –

+0

Ich sehe das Problem jetzt, danke! Ich denke, dass Sie die @ InverseFalcon Antwort in meinem Code implementieren können und das Problem beheben sollten! –

0

Eine schnelle workaraound ist Ihre Daten in zwei Schritten zu laden

1/LOAD CSV, erstellen Knoten mit leerer Array-Eigenschaft

2/LOAD CSV erneut, setzen Sie E-Mails + =

3/Optional, abhängig von Ihren Daten für jeden Knoten, entfernen Sie Doppel im Array (tun Sie es mit einem benutzerdefinierten Verfahren).

sollte es tun. Ich bin auch nicht sehr glücklich mit der CASE-Syntax

+0

Danke! Ich dachte darüber nach, aber es stellt sich heraus, dass du es in einem Durchgang mit "COALESCE" machen kannst. –

+0

Ich neige dazu, zu verschmelzen. Es ist eine bessere Antwort. –

Verwandte Themen