2017-06-29 26 views
1

Neo4Jにデータをロードしようとしています。私はPersonノードがすでにセットアップされています。今、このノードは配列(またはコレクション)であるべきemailプロパティを持つ必要があります。基本的には、emailプロパティは複数の値を持つ必要がある、のように -Neo4JでCypherを使用して既存のノードに複数の値を追加する方法

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

私はここに同様の質問に遭遇しましたが、答えの全ては、ノード自体がを作成時に複数のプロパティ値にを設定することを示しています。 this答えからこのようなクエリ -

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

しかし、私の場合の問題点は、Personノードはすでにを作成し、私は今それにemailプロパティを設定する必要があるということです。

これは私がロードする必要があり、データの小さなサブセットである -

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] 

私のクエリはジェネリックにする必要があるので、また、データは、数千行でCSVファイルから来ている、私は」することができます各ノードPersonノードのプロパティを設定します。

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

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

私が考えていたように、これはちょうど、最新の値にemailプロパティを上書きする -

が、私はこのサブセットで電子メール財産の創造をテストしていたとき、私の最初の試みは、これはでしたクエリ。

はここの回答で、とサイファーのドキュメント上で見た後、私はのNeo4jはあなたがプロパティ値として配列/コレクション(同じタイプの複数の値)を設定することができ、その後、私はこれを試したことが判明 -

enter image description here

あなたが見ることができるように、emailプロパティは、現在複数の値を持っている -

// 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 

ここでの結果です。

しかし、私のCSVファイルには何千もの行があるので、これを行うには一般的なクエリが必要です。

私はドキュメントhereごとにCASE文を使用して考えて、これを試してみました -

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 

しかし、これは単なるエラースロー - mismatched input CASE expecting ;を。 CASEエラーが固定されている場合でも、

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 

をしかし、これはうまくいく場合は私も知っていない -

私はCSVは、このようなファイルのための汎用的な方法として、このクエリを使用することができます期待していました。

私は本当に困っていて、助けていただければ幸いです。ありがとうございました。

答えて

2

取得しようとしている値がnullの場合にCOALESCE()を使用してデフォルト値を使用できます。

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

あなたはノードのプロパティとして値の配列を設定しているときはいつでも、それはあなたの代わりに元に関係を持つ別のノードとしてこれらをモデル化する可​​能性があるかどうかを検討することをお勧めします:あなたはこのようにそれを使用する場合がありますノード。

この場合、:TESTPERSONノードとの関係が1つの電子メールノード:電子メールごとの電子メールノード、複数の関係:TESTPERSONから複数:電子メール。

一意性制約をサポートしたい場合は、一意性制約をサポートできるという利点があります。システム内の電子メールで、システムに電子メールを送信すると、電子メールで人をすばやく検索できます。索引またはユニーク制約を使用します。問合せで索引を使用して電子メールを検索します。電子メールの所有者をトラバースする関係は1つのみです。

ノード上のコレクションに値がある場合、コレクション内の値にインデックスルックアップを使用することはできません。そのため、現在のモデルでは電子メールで人物をすばやく検索することはできません。

+0

ありがとう!これは完全に機能しました。私が実行したクエリは次のとおりです - 'CSVをヘッダからロード 'fileURL" AS行 FIELDTERMINATOR' | ' MATCH(n:TESTPERSON {id:toInt(line.Personid)}) SET n.email = COALESCE(n.email、[])+ line.email' –

0

MERGEを使用して、このソリューションをお試しください:重複ノードのMERGEコマンド世話

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 

、その後、我々はノードがON CREATE SETで作成された場合にのみプロパティを設定していて、ノードがすでにあるときデータベース(すなわちON MATCH SET)には、プロパティに電子メールアドレスを追加します。

希望に役立ちます。

これはのNeo4jに私の結果である: enter image description here

+0

こんにちは、ありがとうございました!私のコードには既に 'Person'ノードが設定されていますので、この行はまったく実行されません。' ON CREATE SET p.mail = line.email'。これは 'p.mail'が' null'になり、 'ON MATCH SET'節に達すると' ON MATCH SET p.mail = p.mail + ' - ' + line.email'というコードが 'この時点で 'p.mail'はまだ' null'であり、 'null'に何かを追加すると' null'を返すので、nullです。 また、スクリーンショットのコードでは、 'email'は' -'を使って文字列を連結した文字列プロパティですが、代わりに 'email'を文字列の配列にする必要があります。思考? –

+0

私は今、問題を参照してください、ありがとう!私はあなたのコードで@InverseFalconの答えを実装することができると思う問題を解決する必要があります! –

0

迅速workaraoundは空の配列プロパティで

2/LOADをノードを作成し、2つの段階

1/LOADのCSVにデータをロードすることですCSVを再度設定し、電子メール+ =

3/Optionnal、各ノードのデータに応じて、配列内の倍精度を削除します(カスタムプロシージャで行います)。

する必要があります。私もCASEの構文に満足していません

+0

ありがとう!私はこの方法を考えていましたが、あなたは 'COALESCE'で1回のパスでそれを行うことができます。 –

+0

私は合体を忘れる傾向があります。それは良い答えです。 –

関連する問題