在neo4j中合并CSV,避免重复

问题描述 投票:1回答:2

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

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

如果在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
database csv import neo4j merge
2个回答
0
投票

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

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

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

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
© www.soinside.com 2019 - 2024. All rights reserved.