在neo4j中合并CSV,避免重复

时间:2018-01-03 10:08:11

标签: database csv import neo4j merge

我正在使用neo4j和一组电影数据集。 https://neo4j.com/developer/example-data/

我现在想要使用grouplens的CSV文件导入和更新我的数据库 https://grouplens.org/datasets/movielens/

如果在csv文件中写入的影片已经在数据库中,我想更新(合并)从csv文件中检索的属性。

如果电影尚未在数据库中,我想为此创建一个新记录。

一个问题是,csv文件中的电影在标题中有发布年份,而DB中的条目没有。因此,我还需要在csv文件中拆分标题。

我尝试了这个,但它确实有效:

 USING PERIODIC COMMIT 500
 LOAD CSV WITH HEADERS FROM "File:///movies.csv" AS csvLine 
 Merge (movie:Movie{title:split(csvLine.title,"()")})
 Create (a:Movie{id:csvLine.movieId,genre:csvLine.genres})
 Return a.title

2 个答案:

答案 0 :(得分:0)

我建议您安装APOC程序插件,其中包含许多有用的字符串函数来帮助您:

https://github.com/neo4j-contrib/neo4j-apoc-procedures

Download the APOC plugin并将其复制到您的$NEO4J_HOME/plugins目录

通过添加此行

启用neo4j.conf配置文件中的过程

dbms.security.procedures.unrestricted=apoc.*

重启Neo4j。

APOC程序包含apoc.text.replace函数,该函数接受正则表达式:

WITH "Toy Story (1995)" AS title
RETURN trim(apoc.text.replace(title, "\\([0-9]+\\)",""))


╒═══════════════════════════════════════════════════════════╕
│"trim(apoc.text.replace(title, \"\\\\([0-9]+\\\\)\",\"\"))"│
╞═══════════════════════════════════════════════════════════╡
│"Toy Story"                                                │
└───────────────────────────────────────────────────────────┘

然后,您可以在LOAD CSV声明中使用它:

 USING PERIODIC COMMIT 500
 LOAD CSV WITH HEADERS FROM "File:///movies.csv" AS csvLine 
 MERGE (movie:Movie {title: trim(apoc.text.replace(csvLine.title, "\\([0-9]+\\)","")) })
 CREATE (a:Movie{id:csvLine.movieId,genre:csvLine.genres})
 RETURN a.title

答案 1 :(得分:0)

当查询未按预期运行时,最好开发一个最小查询来检查您的假设并查看哪些内容出错。

例如,您可以使用它来测试您的拆分是否按预期工作:

LOAD CSV WITH HEADERS FROM "File:///movies.csv" AS csvLine 
with csvLine limit 1
return csvLine.title, split(csvLine.title,"()")

你能够很快发现分裂并没有按照你的想法行事,这里的多个分隔符不起作用,即使它们确实存在,你也需要做更多的事情。您的查询以获取拆分结果的相关部分。

获得所需内容的一种方法是拆分'(',获取结果字符串数组的第一个元素,然后右键修剪它以消除任何可能的空格:{ {1}}

需要解决的另一件事是找出你在MERGE之后在CREATE子句中尝试做什么。我有一种感觉你只想要一个MERGE,然后想要在之后设置值(否则你要创建两个独立的:电影节点在这里,一个用于标题,另一个用于id和类型,它没有&#39有意义的。)

试试这个:

rTrim(split(csvLine.title, '(')[0])