繁体   English   中英

在neo4j中合并CSV以避免重复

[英]Merge CSV in neo4j avoiding duplicates

我正在使用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

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

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

下载APOC插件并将其复制到$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

当查询无法按预期工作时,最好开发一个最小查询以检查您的假设并查看出了什么问题。

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

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

您将能够快速看到拆分未按您预期的那样运行,此处的多个定界符不起作用,即使它们成功了,您也需要在查询中做更多的工作才能获得相关内容的一部分。分割结果。

获得所需内容的一种方法是在'('周围进行拆分,获取结果字符串数组的第一个元素,然后对其进行右修剪以消除任何可能的空格: rTrim(split(csvLine.title, '(')[0])

需要解决的另一件事是在MERGE之后的CREATE子句中找出​​您要执行的操作。 我有一种感觉,您只是想要一个MERGE,然后又想设置值(否则,您将在此处创建两个单独的:Movie节点,一个用于标题,另一个用于id和体裁,这没有意义。 )。

尝试这个:

USING PERIODIC COMMIT 500
LOAD CSV WITH HEADERS FROM "File:///movies.csv" AS csvLine 
MERGE (movie:Movie{title: rTrim(split(csvLine.title, '(')[0])})
SET movie.id = toInteger(csvLine.movieId), movie.genres = csvLine.genres

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM