Ошибка проверки ограничения схемы Neo4J - PullRequest
0 голосов
/ 23 декабря 2018

Общий фон
В настоящее время я пытаюсь записать запросы neo4j в функции, которые будут использоваться в колбе.
Я хочу, чтобы функция загружала данные из файла CSV, который обновляется сампериодически и создавать новые узлы и отношения по мере необходимости.

Я пытался следовать приведенной здесь структуре функции:
https://github.com/nicolewhite/neo4j-flask/blob/master/blog/models.py

Я тестировал зашифрованные запросы neo4j отдельно, и в настоящее время у меня возникли две проблемы (Вторую проблему py2neo выложу в отдельном посте).

title_id,title  
T1,Article Title 1  
T2,Article Title 2 

Я изменил файл csv, добавив вручную строки, например:

title_id,title  
T1,Article Title 1  
T2,Article Title 2 
T3,TEST

Мой файл csv с ключевыми словами выглядит следующим образом:

title_id,keyword_id,keyword  
T1,K1,aaa  
T1,K2,bbb  
T1,K3,ccc  
T1,K4,ddd  
T2,K1,aaa  
T2,K5,eee  
T2,K6,fff  
T2,K4,ddd  

АналогичноЯ добавляю новые ключевые слова для тестирования следующим образом:

title_id,keyword_id,keyword  
T1,K1,aaa  
T1,K2,bbb  
T1,K3,ccc  
T1,K4,ddd  
T2,K1,aaa  
T2,K5,eee  
T2,K6,fff  
T2,K4,ddd  
T2,K7,TEST  

Мои ограничения следующие:

CREATE CONSTRAINT ON (a_title:Title) ASSERT a_title.t_id IS UNIQUE  
CREATE CONSTRAINT ON (keyword:Keyword) ASSERT keyword.k_id IS UNIQUE  

Первая проблема, с которой я столкнулся, это проблема LOAD CSV.

Мой код py2neo выглядит следующим образом:

def create_titles(self):
    #
    query = '''
    'LOAD CSV WITH HEADERS FROM "file:///1209test_titles.csv" AS csvLine1 WITH csvLine1 ' \
    'WHERE csvLine1.title_id IS NOT NULL MERGE (a_title:Title{t_id:csvLine1.title_id,Title:csvLine1.title})'
    '''


    return graph.run(query)

Однако, когда я пытаюсь создать новый узел заголовка, добавляя новые данные в мой CSV-файл, я сталкиваюсь с ошибкой ограничения, сообщающей мнеузел, который я только что уже существует.

Я пытался следовать найденному здесь ответу:
Neo4j Загружать CSV, только когда уникален
Мой текущий код LOAD CSV, в котором я тестируюсреда браузера выглядит следующим образом:

LOAD CSV WITH HEADERS FROM "file:///1209test_titles.csv" AS csvLine1
WITH csvLine1
WHERE csvLine1.title_id IS NOT NULL
MERGE (a_title:Title)
ON MATCH SET a_title.t_id = csvLine1.title_id
ON MATCH SET a_title.Title = csvLine1.title

... но все равно выдает ошибку ограничения.

(Для сравнения я попытался выполнить запрос шифрования ключевых слов, но мне показалось, чтоработает нормально без ошибок)

  query2 = 'LOAD CSV WITH HEADERS FROM 

"file:///1209test_titleid_kwid_kw.csv" AS csvLine3 
WITH csvLine3 WHERE csvLine3.title_id IS NOT NULL   MERGE(keyword:Keyword{k_id:csvLine3.keyword_id,Keyword:csvLine3.keyword})   WITH csvLine3, keyword MATCH(title:Title{t_id:csvLine3.title_id}) MERGE(title)-[r1:HAS_KEYWORDS]->(keyword)'

graph.run(query2)

Я не совсем уверен, что я делаю неправильно, и в чем разница между созданием моего узла ключевых слов и созданием заголовка узла ... (После проверки моих файлов, добавление информации в файл заголовка csv, используемый для работы ...)

Большое спасибо,

Эрик

1 Ответ

0 голосов
/ 24 декабря 2018

Вам необходимо выполнить MERGE, используя уникальное свойство (или свойства), и только после MERGE вы можете использовать один из вариантов SET.

Приведенный вами подход не будет работать:

LOAD CSV WITH HEADERS FROM "file:///1209test_titles.csv" AS csvLine1
WITH csvLine1
WHERE csvLine1.title_id IS NOT NULL
MERGE (a_title:Title)
ON MATCH SET a_title.t_id = csvLine1.title_id
ON MATCH SET a_title.Title = csvLine1.title

MERGE здесь сделает его соответствующим всему, что соответствует шаблону, поэтому он будет соответствовать всем: Заголовочные узлы в вашей базе данных, а затем установите эти свойства для всех из них (и затем повторите один и тот же процесс для каждой строки вCSV).

Вам нужно это вместо:

LOAD CSV WITH HEADERS FROM "file:///1209test_titles.csv" AS csvLine1
WITH csvLine1
WHERE csvLine1.title_id IS NOT NULL
MERGE (a_title:Title {t_id:csvLine1.title_id})
ON MATCH SET a_title.Title = csvLine1.title // or just SET if you want to set it in all cases
...