使用 Cypher 导入 CSV 文件
引言
本教程将向您展示如何使用 LOAD CSV
从 CSV 文件导入数据。
在本例中,我们提供了三个 CSV 文件:人物列表、电影列表以及这些人物在每部电影中扮演的角色列表。
CSV 文件可以存储在数据库服务器上,然后通过 file://
URL 进行访问。此外,LOAD CSV
也支持通过 HTTPS
、HTTP
和 FTP
访问 CSV 文件。LOAD CSV
将遵循 HTTP
重定向,但出于安全原因,它不会遵循更改协议的重定向,例如从 HTTPS
重定向到 HTTP
的情况。
在本例中,我们将使用托管在 github 上的 CSV 文件。
设置
使用以下 Cypher 查询,我们将为每个人创建一个节点,为每部电影创建一个节点,并在两者之间创建一个关系,用属性表示角色。我们还记录了每部电影的制作国家。
让我们从导入人物开始。我们使用的 CSV 文件如下所示
id,name 1,Charlie Sheen 2,Oliver Stone 3,Michael Douglas 4,Martin Sheen 5,Morgan Freeman
导入人物
使用 LOAD CSV WITH HEADERS
导入人物
LOAD CSV WITH HEADERS FROM "https://raw.githubusercontent.com/neo4j/neo4j/2.3/manual/cypher/cypher-docs/src/docs/graphgists/import/persons.csv" AS csvLine
CREATE (p:Person {id: toInteger(csvLine.id), name: csvLine.name})
导入电影
这一次,我们还创建了与电影制作国家的关系。如果您将数据存储在 SQL 数据库中,这就是一对多关系类型。
我们使用 MERGE
创建代表国家的节点。使用 MERGE
可以避免在同一国家制作多部电影时创建重复的国家节点。当与 LOAD CSV
一起使用 MERGE
或 MATCH
时,我们需要确保在我们合并的属性上有一个索引或唯一约束。这将确保查询以高性能方式执行。
在运行连接 Movies
和 Country
节点的查询之前,我们将在 Country
标签的 name 属性上创建一个索引,以确保查询尽快运行
CREATE INDEX ON :Country(name)
id,title,country,year 1,Wall Street,USA,1987 2,The American President,USA,1995 3,The Shawshank Redemption,USA,1994
LOAD CSV WITH HEADERS FROM "https://raw.githubusercontent.com/neo4j/neo4j/2.3/manual/cypher/cypher-docs/src/docs/graphgists/import/movies.csv" AS csvLine
MERGE (country:Country {name: csvLine.country})
CREATE (movie:Movie {id: toInteger(csvLine.id), title: csvLine.title, year:toInteger(csvLine.year)})
CREATE (movie)-[:MADE_IN]->(country)
创建唯一性约束
在创建 `Person` 和 `Movie` 之间的关系之前,我们必须准备数据。
我们将索引 Person
和 Movie
节点上的 id
属性。id 属性是一个临时属性,用于在导入第三个文件时查找适合于关系的节点。通过索引 id 属性,节点查找(例如通过 MATCH
)将快得多。由于我们期望每个集合中的 id 是唯一的,因此我们将创建一个唯一约束。这可以保护我们免受无效数据的影响,因为如果存在多个具有相同 id
属性的节点,约束创建将失败。创建唯一约束也会创建一个唯一索引(比常规索引更快)。
CREATE CONSTRAINT ON (person:Person) ASSERT person.id IS UNIQUE
CREATE CONSTRAINT ON (movie:Movie) ASSERT movie.id IS UNIQUE
使用 PERIODIC COMMIT
现在导入关系就是找到节点,然后在它们之间创建关系的问题了。
对于此查询,我们将使用 USING PERIODIC COMMIT
,这对于处理大型 CSV 文件的查询很有帮助。此提示告诉 Neo4j,查询可能会累积过多的事务状态,因此需要定期提交。
在本例中,我们还将每次提交的行数限制设置为 500
。
personId,movieId,role 1,1,Bud Fox 4,1,Carl Fox 3,1,Gordon Gekko 4,2,A.J. MacInerney 3,2,President Andrew Shepherd 5,3,Ellis Boyd 'Red' Redding
USING PERIODIC COMMIT 500
LOAD CSV WITH HEADERS FROM "https://raw.githubusercontent.com/neo4j/neo4j/2.3/manual/cypher/cypher-docs/src/docs/graphgists/import/roles.csv" AS csvLine
MATCH (person:Person { id: toInteger(csvLine.personId)}),(movie:Movie { id: toInteger(csvLine.movieId)})
CREATE (person)-[:PLAYED { role: csvLine.role }]->(movie)
删除唯一性约束
最后,由于 id
属性仅用于导入关系,我们可以删除所有 Movie
和 Person
节点上的约束和 id
属性。
DROP CONSTRAINT ON (person:Person) ASSERT person.id IS UNIQUE
DROP CONSTRAINT ON (movie:Movie) ASSERT movie.id IS UNIQUE
MATCH (n) WHERE n:Person OR n:Movie REMOVE n.id
此页面有帮助吗?