2016-12-22 5 views
0

ノードが存在しない場合は、既存のノードを新しいデータで更新し、新しいデータを作成する必要があります。私は次のクエリでこれを実行しようとしています:Neo4jがCSVファイルのノードを更新する

USING PERIODIC COMMIT 
LOAD CSV WITH HEADERS FROM 
'file:///C:/Users/Zona5/Documents/Neo4j/check/import/cd1_5.csv' AS  line1 
MERGE (c:Company {companyNumber:line1.companyNumber}) 
WITH c, line1 
MERGE (ca:CompanyAddress) 
ON CREATE SET ca.county=line1.County 
ON MATCH SET ca.county=line1.County 
ON CREATE SET ca.country=line1.Country 
ON MATCH SET ca.country=line1.Country 
ON CREATE SET ca.postCode=line1.postCode 
ON MATCH SET ca.postCode=line1.postCode 
ON CREATE SET ca.poBox=line1.POBox 
ON MATCH SET ca.poBox=line1.POBox 
ON CREATE SET ca.careOf=line1.CareOf 
ON MATCH SET ca.careOf=line1.CareOf 
ON CREATE SET ca.addressLine1=line1.AddressLine1 
ON MATCH SET ca.addressLine1=line1.AddressLine1 
ON CREATE SET ca.addressLine2=line1.AddressLine2 
ON MATCH SET ca.addressLine2=line1.AddressLine2 
MERGE (c)-[:HAS_COMPANY_ADDRESS]->(ca) 

クエリは長時間実行されていますが、データベースサイズは増加しません。

私はここで間違ったことをしていますが、ノードを更新する別の方法はありますか?

答えて

1

MERGE clauseはこれを正確に行います。ドキュメントから:

MERGEは、既存のノードに一致し、それらをバインドするか、新しいデータを作成してバインドします。これはMATCHとCREATEの組み合わせのようなもので、データが一致または作成された場合の処理​​を指定することもできます。

あなたのクエリを見てみましょう。この行:line1.companyNumberあなたのCSVファイルでこの行のためには何でもの値を持つプロパティcompanyNumberを持っているラベルCompanyを持つ既存のノードが存在しない場合

MERGE (c:Company {companyNumber:line1.companyNumber}) 

は病気ラベルCompanyで新しいノードを作成します。これは、リレーショナルデータベースのプライマリキーに似ています。 companyNumberはノードCompanyを一意に識別し、このプロパティーに同じ値を持つ重複ノードを作成したくないものです。

あなたはalso create a uniqueness constraintは、データベース・スキーマ・レベルでこれを強制する必要があります。

CREATE CONSTRAINT ON (c:Company) ASSERT c.companyNumber IS UNIQUE; 

をしかし、そうでない場合は、この最初の部分はよさそうです。

今すぐあなたのクエリの次の部分:

MERGE (ca:CompanyAddress) 
ON CREATE SET ca.county=line1.County 
ON MATCH SET ca.county=line1.County 
ON CREATE SET ca.country=line1.Country 
ON MATCH SET ca.country=line1.Country 
ON CREATE SET ca.postCode=line1.postCode 
ON MATCH SET ca.postCode=line1.postCode 
ON CREATE SET ca.poBox=line1.POBox 
ON MATCH SET ca.poBox=line1.POBox 
ON CREATE SET ca.careOf=line1.CareOf 
ON MATCH SET ca.careOf=line1.CareOf 
ON CREATE SET ca.addressLine1=line1.AddressLine1 
ON MATCH SET ca.addressLine1=line1.AddressLine1 
ON CREATE SET ca.addressLine2=line1.AddressLine2 
ON MATCH SET ca.addressLine2=line1.AddressLine2 

MERGEは、パターンを取り、それが存在しない場合、データを作成し、このパターンが存在するかどうかを確認するために、グラフを検索します。 MERGEに指定するパターンは、ラベルCompanyAddressのノードです。これはMATCHすべてノードのラベルはCompanyAddressで、プロパティには関係ありません。その後、次のSETステートメントは、のすべてのプロパティを更新します。CompanyAddressノード。つまり、クエリのこの部分は最大でCompanyAddressノードを作成し、既存のCompanyAddressノードはすべて、CSVファイルの最後の行が何であっても同じプロパティ値を持つことになります。

代わりにあなたがMERGE使用する必要があり、複数のプロパティ:

MERGE (ca:CompanyAddress { 
    county: line1.County, 
    country: line1.Country, 
    poBox: line1.POBox, 
    careof: line1.Careof, 
    addressLine1: line1.AddressLine1, 
    addressLine2: line1.AddressLine2 
}) 
MERGE (c)-[:HAS_COMPANY_ADDRESS]->(ca) 

が、一つのフィールドが変更された場合、このアプローチはCompanyAddressのための新しいノードを作成することに注意してください。変更されたアドレスのフィールドを更新する場合は、そのアドレスに固有のIDとそのプロパティのMERGEを導入する必要があります。

UPDATE

Companyノードは一つだけCompanyAddressノードに接続されたデータモデリング制約を考えると、このクエリ:

USING PERIODIC COMMIT 
LOAD CSV WITH HEADERS FROM 
'file:///C:/Users/Zona5/Documents/Neo4j/check/import/cd1_5.csv' AS line1 
MERGE (c:Company {companyNumber:line1.companyNumber}) 
MERGE (c)-[:HAS_COMPANY_ADDRESS]->(ca:CompanyAddress) 
SET ca.county=line1.County, 
    ca.country=line1.Country, 
    ca.postCode=line1.postCode, 
    ca.poBox=line1.POBox, 
    ca.careOf=line1.CareOf, 
    ca.addressLine1=line1.AddressLine1, 
    ca.addressLine2=line1.AddressLine2 

は、彼ら場合HAS_COMPANY_ADDRESS関係で接続されたCompanyCompanyAddressノードを作成します。存在しない場合は、CompanyAddressのプロパティを更新してください。

+0

問題は、数百万の企業が更新され、それらの間に多くの関係があることです。だから、そのアプローチは何百万ものノードを生成し、既存のものを残すでしょう。また、 'CompanyAddress'ラベルの新しいノードが作成されたときに、別の' HAS_COMPANY_ADDRESS'関係を作成しませんか? – Porjaz

+0

各社は1つのCompanyAddressしか持っていませんか?そうすれば、物事はより簡単になります。 –

+0

はい、各会社には、 – Porjaz

関連する問題