GraphGists

引言

本教程将向您展示如何使用 LOAD CSV 从 CSV 文件导入数据。

在本例中,我们提供了三个 CSV 文件:人物列表、电影列表以及这些人物在每部电影中扮演的角色列表。

CSV 文件可以存储在数据库服务器上,然后通过 file:// URL 进行访问。此外,LOAD CSV 也支持通过 HTTPSHTTPFTP 访问 CSV 文件。LOAD CSV 将遵循 HTTP 重定向,但出于安全原因,它不会遵循更改协议的重定向,例如从 HTTPS 重定向到 HTTP 的情况。

在本例中,我们将使用托管在 github 上的 CSV 文件。

设置

使用以下 Cypher 查询,我们将为每个人创建一个节点,为每部电影创建一个节点,并在两者之间创建一个关系,用属性表示角色。我们还记录了每部电影的制作国家。

让我们从导入人物开始。我们使用的 CSV 文件如下所示

persons.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 一起使用 MERGEMATCH 时,我们需要确保在我们合并的属性上有一个索引或唯一约束。这将确保查询以高性能方式执行。

在运行连接 MoviesCountry 节点的查询之前,我们将在 Country 标签的 name 属性上创建一个索引,以确保查询尽快运行

CREATE INDEX ON :Country(name)
movies.csv
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` 之间的关系之前,我们必须准备数据。

我们将索引 PersonMovie 节点上的 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

roles.csv
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 属性仅用于导入关系,我们可以删除所有 MoviePerson 节点上的约束和 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
© . All rights reserved.