2016-12-22 4 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, которая дополнительно позволяет вам указать, что произойдет, если данные будут сопоставлены или созданы.

Итак, давайте посмотрим на ваш запрос. Эта линия:

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

плохо создать новый узел с меткой Company, если нет существующего узла с меткой Company, который имеет свойство companyNumber со значением независимо line1.companyNumber является для этой строки в файле CSV. Это похоже на первичный ключ в реляционной базе данных. 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. Если вы хотите обновить поле по адресу при его изменении, вам нужно ввести уникальный идентификатор для адреса и MERGE по этому свойству.

ОБНОВЛЕНИЕ

С учетом моделирования данных ограничений, что каждый 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 

создаст Company, CompanyAddress узлов, соединенных HAS_COMPANY_ADDRESS отношений, если они не существует, а затем обновлять свойства CompanyAddress.

+0

Проблема в том, что есть миллионы компаний для обновления и много отношений между ними. Таким образом, этот подход привел бы к созданию миллионов узлов и оставил бы существующие. Кроме того, когда новый узел с метки 'CompanyAddress' создан, не создаст ли это другое отношение HAS_COMPANY_ADDRESS'? – Porjaz

+0

Имеет ли каждая компания только 1 CompanyAddress? Если это так упростит ситуацию ... –

+0

Да, у каждой компании есть только один CompanyAddress со свойствами, представленными в примере – Porjaz

Смежные вопросы