LOAD CSV
LOAD CSV 用于将数据从 CSV 文件导入 Neo4j 数据库。
LOAD CSV FROM 'https://data.neo4j.com/bands/artists.csv' (1)
AS row (2)
MERGE (:Artist {name: row[1], year: toInteger(row[2])}) (3)
| 1 | FROM 接受一个包含 CSV 文件所在路径的 STRING 字符串。 |
| 2 | 该子句一次解析一行,将当前行临时存储在用 AS 指定的变量中。 |
| 3 | MERGE 子句访问 row 变量以将数据插入数据库。 |
LOAD CSV 支持本地和远程 URL。本地路径是相对于 Neo4j 安装文件夹解析的。
|
加载 CSV 文件需要加载权限。 |
将 CSV 数据导入 Neo4j
导入本地文件
您可以将 CSV 文件存储在数据库服务器上,然后使用 file:/// URL 访问它们。默认情况下,路径是相对于 Neo4j 导入目录解析的。
1,ABBA,1992
2,Roxette,1986
3,Europe,1979
4,The Cardigans,1992
LOAD CSV FROM 'file:///artists.csv' AS row
MERGE (a:Artist {name: row[1], year: toInteger(row[2])})
RETURN a.name, a.year
| a.name | a.year |
|---|---|
|
|
|
|
|
|
|
|
4 行 添加了 4 个节点,设置了 8 个属性,添加了 4 个标签 |
|
| 有关将数据导入 Aura 实例的方法,请参阅Aura → 导入数据。 |
使用 file:/// URL 时,空格和其他非字母数字字符必须进行URL 编码。 |
文件 URL 的配置设置
- dbms.security.allow_csv_import_from_file_urls
-
此设置确定是否允许
file:///URL。 - server.directories.import
-
此设置指定
file:///URL 解析的根目录。
从远程位置导入
您可以从远程路径上托管的 CSV 文件导入数据。
LOAD CSV 支持通过 HTTPS、HTTP 和 FTP(带或不带凭据)访问 CSV 文件。它还遵循重定向,但更改协议的重定向除外(出于安全原因)。
|
强烈建议仅通过 HTTPS 等安全协议而非 HTTP 等不安全协议加载资源。这可以通过将加载权限限制为仅使用安全协议的受信任源来实现。如果允许不安全协议绝对无法避免,Neo4j 会在内部采取措施,在其限制范围内增强这些请求的安全性。然而,这意味着虚拟主机上的不安全 URL 将无法运行,除非您将 JVM 参数 |
1,ABBA,1992
2,Roxette,1986
3,Europe,1979
4,The Cardigans,1992
LOAD CSV FROM 'https://data.neo4j.com/bands/artists.csv' AS row
MERGE (a:Artist {name: row[1], year: toInteger(row[2])})
RETURN a.name, a.year
| a.name | a.year |
|---|---|
|
|
|
|
|
|
|
|
4 行 添加了 4 个节点,设置了 8 个属性,添加了 4 个标签 |
|
1,ABBA,1992
2,Roxette,1986
3,Europe,1979
4,The Cardigans,1992
LOAD CSV FROM 'ftp://<username>:<password>@<domain>/bands/artists.csv' AS row
MERGE (a:Artist {name: row[1], year: toInteger(row[2])})
RETURN a.name, a.year
| a.name | a.year |
|---|---|
|
|
|
|
|
|
|
|
4 行 添加了 4 个节点,设置了 8 个属性,添加了 4 个标签 |
|
从云 URI 导入
您可以从多种不同的云存储中导入数据
有关如何设置云存储访问权限,请参阅操作手册 → 从云存储加载转储。
从 Azure 云存储 URI 导入
您可以从 Azure 云存储 URI 中托管的 CSV 文件导入数据。
1,ABBA,1992
2,Roxette,1986
3,Europe,1979
4,The Cardigans,1992
LOAD CSV FROM 'azb://azb-account/azb-container/artists.csv' AS row
MERGE (a:Artist {name: row[1], year: toInteger(row[2])})
RETURN a.name, a.year
| a.name | a.year |
|---|---|
|
|
|
|
|
|
|
|
4 行 添加了 4 个节点,设置了 8 个属性,添加了 4 个标签 |
|
从 Google 云存储 URI 导入
您可以从 Google 云存储 URI 中托管的 CSV 文件导入数据。
1,ABBA,1992
2,Roxette,1986
3,Europe,1979
4,The Cardigans,1992
LOAD CSV FROM 'gs://gs-bucket/artists.csv' AS row
MERGE (a:Artist {name: row[1], year: toInteger(row[2])})
RETURN a.name, a.year
| a.name | a.year |
|---|---|
|
|
|
|
|
|
|
|
4 行 添加了 4 个节点,设置了 8 个属性,添加了 4 个标签 |
|
从 AWS S3 URI 导入
您可以从 AWS S3 URI 中托管的 CSV 文件导入数据。
1,ABBA,1992
2,Roxette,1986
3,Europe,1979
4,The Cardigans,1992
LOAD CSV FROM 's3://aws-bucket/artists.csv' AS row
MERGE (a:Artist {name: row[1], year: toInteger(row[2])})
RETURN a.name, a.year
| a.name | a.year |
|---|---|
|
|
|
|
|
|
|
|
4 行 添加了 4 个节点,设置了 8 个属性,添加了 4 个标签 |
|
使用动态列导入 CSV 文件
CSV 列可以动态引用,将标签映射到图中的节点。这使得数据处理更加灵活,允许标签从 CSV 列值中填充,而无需手动指定每个条目。它还降低了 Cypher® 注入的风险。(有关 Cypher 注入的更多信息,请参阅Neo4j 知识库 → 防范 Cypher 注入)。
Id,Label,Name
1,Band,The Beatles
2,Band,The Rolling Stones
3,Band,Pink Floyd
4,Band,Led Zeppelin
LOAD CSV WITH HEADERS FROM 'file:///bands-with-headers.csv' AS line
MERGE (n:$(line.Label) {name: line.Name})
RETURN n AS bandNodes
| bandNodes |
|---|
|
|
|
|
行数: 4 |
使用动态值的 MERGE 查询可能不如使用静态值的查询性能好。这是因为 Cypher 规划器在规划查询时使用静态可用信息来确定是否使用索引,这在使用动态值时是不可能的。有关更多信息,请参阅MERGE 使用动态节点标签和关系类型 → 性能注意事项。 |
导入压缩的 CSV 文件
LOAD CSV 可以读取用 ZIP 或 gzip 压缩的本地 CSV 文件。ZIP 归档文件可以有任意目录结构,但只能包含一个 CSV 文件。
LOAD CSV FROM 'file:///artists.zip' AS row
MERGE (:Artist {name: row[1], year: toInteger(row[2])})
| 您不能从远程 URL 加载压缩的 CSV 文件。 |
从关系数据库导入数据
如果源数据来自关系模型,那么评估如何最大限度地利用迁移到图数据模型是值得的。在运行导入之前,请考虑如何将数据建模为图,并在运行导入时相应地调整其结构(请参阅图数据建模)。
来自关系数据库的数据可能由一个或多个 CSV 文件组成,具体取决于源数据库结构。一种高效的方法是多次运行 LOAD CSV,以将节点和关系分开导入。
源文件books.csv包含作者和书籍的信息。从图的角度来看,这些是具有不同标签的节点,因此需要不同的查询来加载它们。
此示例对该文件执行多次 LOAD CSV,每次都专注于创建一种实体类型。
id,title,author,publication_year,genre,rating,still_in_print,last_purchased
19515,The Heights,Anne Conrad,2012,Comedy,5,true,2023/4/12 8:17:00
39913,Starship Ghost,Michael Tyler,1985,Science Fiction|Horror,4.2,false,2022/01/16 17:15:56
60980,The Death Proxy,Tim Brown,2002,Horror,2.1,true,2023/11/26 8:34:26
18793,Chocolate Timeline,Mary R. Robb,1924,Romance,3.5,false,2022/9/17 14:23:45
67162,Stories of Three,Eleanor Link,2022,Romance|Comedy,2,true,2023/03/12 16:01:23
25987,Route Down Below,Tim Brown,2006,Horror,4.1,true,2023/09/24 15:34:18
// Create `Book` nodes
LOAD CSV WITH HEADERS FROM 'https://data.neo4j.com/importing-cypher/books.csv' AS row
MERGE (b:Book {id: row.id, title: row.title})
MERGE (a:Author {name: row.author});
// Create `WROTE` relationships
LOAD CSV WITH HEADERS FROM 'https://data.neo4j.com/importing-cypher/books.csv' AS row
MATCH (a:Author{name: row.author})
MATCH (b:Book{id: row.id})
MERGE (a)-[:WROTE]->(b);
Added 11 nodes, Set 17 properties, Added 11 labels
Created 6 relationships
文件acted_in.csv包含演员与他们出演的电影之间的关系数据(来自persons.csv和movies.csv)。演员和电影通过其 ID 列 person_tmdbId 和 movieId 链接。
该文件还包含演员在电影中扮演的角色,并将其作为关系属性导入 Neo4j。
movieId,person_tmdbId,role
1,12899,Slinky Dog (voice)
1,12898,Buzz Lightyear (voice)
...
导入此数据集需要三个 LOAD CSV 子句:前两个从 persons.csv 创建 Person 节点,从 movies.csv 创建 Movie 节点,第三个从 acted_in.csv 添加 :ACTED_IN 关系。
// Create person nodes
LOAD CSV WITH HEADERS FROM 'https://data.neo4j.com/importing-cypher/persons.csv' AS row
MERGE (p:Person {name: row.name, tmdbId: row.person_tmdbId});
// Create movie nodes
LOAD CSV WITH HEADERS FROM 'https://data.neo4j.com/importing-cypher/movies.csv' AS row
MERGE (m:Movie {movieId: row.movieId, title: row.title});
// Create relationships
LOAD CSV WITH HEADERS FROM 'https://data.neo4j.com/importing-cypher/acted_in.csv' AS row
MATCH (p:Person {tmdbId: row.person_tmdbId})
MATCH (m:Movie {movieId: row.movieId})
MERGE (p)-[r:ACTED_IN {role: row.role}]->(m);
Added 444 nodes, Set 888 properties, Added 444 labels
Added 93 nodes, Set 186 properties, Added 93 labels
Created 372 relationships, Set 372 properties
| 有关将 Northwind 数据集从 Postgres 导入 Neo4j 的指南,请参阅“入门指南”中的教程:将数据从关系数据库导入 Neo4j。 |
创建额外的节点标签
在 Neo4j 中,一个节点可以有多个标签,而在关系型设置中,混合实体并不那么直接。例如,Neo4j 中的一个节点可以同时标记为 Dog 和 Actor,而在关系模型中,狗和演员是独立的实体。
导入关系数据集后,根据用例,可能会添加更多标签。如果您在查询中使用它们,额外的标签可以加快定位节点的速度。
Person 节点上添加额外的 Actor 标签来自 acted_in.csv 的 :ACTED_IN 关系隐式地将演员定义为人物的一个子集。以下查询会为所有具有传出 :ACTED_IN 关系的 Person 添加一个额外的 Actor 标签。
MATCH (p:Person)-[:ACTED_IN]->()
WITH DISTINCT p
SET p:Actor
Added 353 labels
导入期间预处理数据
将 CSV 列转换为 Neo4j 数据类型
LOAD CSV 将所有导入的 CSV 数据作为 STRING 属性插入。然而,Neo4j 支持多种数据类型,使用适当类型存储数据可以更有效地查询和使用特定类型的 Cypher 函数处理数据。
文件persons.csv中的列 person_tmdbId 和 born 分别包含 INTEGER 和 DATE 值。函数 toInteger() 和 date() 允许在导入之前将这些值转换为适当的类型。
person_tmdbId,bio,born,bornIn,died,person_imdbId,name,person_poster,person_url
3,"Legendary Hollywood Icon Harrison Ford was born on July 13, 1942 in Chicago, Illinois. His family history includes a strong lineage of actors, radio personalities, and models. Harrison attended public high school in Park Ridge, Illinois where he was a member of the school Radio Station WMTH. Harrison worked as the lead voice for sports reporting at WMTH for several years. Acting wasn’t a major interest to Ford until his junior year at Ripon College when he first took an acting class...",1942-07-13,"Chicago, Illinois, USA",,148,Harrison Ford,https://image.tmdb.org/t/p/w440_and_h660_face/5M7oN3sznp99hWYQ9sX0xheswWX.jpg,https://themoviedb.org/person/3
...
LOAD CSV WITH HEADERS FROM 'https://data.neo4j.com/importing-cypher/persons.csv' AS row
MERGE (p:Person {tmdbId: toInteger(row.person_tmdbId)})
SET p.name = row.name, p.born = date(row.born)
RETURN
p.name AS name,
p.tmdbId AS tmdbId,
p.born AS born
LIMIT 5
| name | tmdbId | born |
|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5 行 添加了 444 个节点,设置了 1332 个属性,添加了 444 个标签 |
||
有关类型转换函数的列表,请参阅数据值转换。
处理 null 值
Neo4j 不存储 null 值。CSV 文件中的 null 或空字段可以在 LOAD CSV 中跳过或替换为默认值。
null 值的文件在文件 companies.csv 中,有些行没有为某些列指定值。示例展示了几种处理 null 值的选项。
Id,Name,Location,Email,BusinessType
1,Neo4j,San Mateo,contact@neo4j.com,P
2,AAA,,info@aaa.com,
3,BBB,Chicago, ,G
,CCC,Michigan,info@ccc.com,G
null 值LOAD CSV WITH HEADERS FROM 'file:///companies.csv' AS row
WITH row
WHERE row.Id IS NOT NULL
MERGE (c:Company {id: row.Id})
null 值提供默认值LOAD CSV WITH HEADERS FROM 'file:///companies.csv' AS row
WITH row
WHERE row.Id IS NOT NULL
MERGE (c:Company {id: row.Id, hqLocation: coalesce(row.Location, "Unknown")})
STRING 值更改为 null 值(不存储)LOAD CSV WITH HEADERS FROM 'file:///companies.csv' AS row
WITH row
WHERE row.Id IS NOT NULL
MERGE (c:Company {id: row.Id})
SET c.email = nullIf(trim(row.Email), "")
null 值不存储在数据库中。一种选择性地移除某些值的策略是将它们映射为 null 值。上一个查询中的空 STRING 值就是一个例子。 |
拆分列表值
函数 split() 允许将包含元素的 STRING 字符串转换为列表。
文件movies.csv包含一个标题行和总共 94 行。
列 languages 和 genres 包含类似列表的值。两者都由竖线 | 分隔,而 split() 允许在将其插入数据库之前将其转换为 Cypher 列表。
movieId,title,budget,countries,movie_imdbId,imdbRating,imdbVotes,languages,plot,movie_poster,released,revenue,runtime,movie_tmdbId,movie_url,year,genres
1,Toy Story,30000000.0,USA,114709,8.3,591836,English,A cowboy doll is profoundly threatened and jealous when a new spaceman figure supplants him as top toy in a boy's room.,https://image.tmdb.org/t/p/w440_and_h660_face/uXDfjJbdP4ijW5hWSBrPrlKpxab.jpg,1995-11-22,373554033.0,81,862,https://themoviedb.org/movie/862,1995,Adventure|Animation|Children|Comedy|Fantasy
2,Jumanji,65000000.0,USA,113497,6.9,198355,English|French,"When two kids find and play a magical board game, they release a man trapped for decades in it and a host of dangers that can only be stopped by finishing the game.",https://image.tmdb.org/t/p/w440_and_h660_face/vgpXmVaVyUL7GGiDeiK1mKEKzcX.jpg,1995-12-15,262797249.0,104,8844,https://themoviedb.org/movie/8844,1995,Adventure|Children|Fantasy
...
LOAD CSV WITH HEADERS FROM 'https://data.neo4j.com/importing-cypher/movies.csv' AS row
MERGE (m:Movie {id: toInteger(row.movieId)})
SET
m.title = row.title,
m.imdbId = toInteger(row.movie_imdbId),
m.languages = split(row.languages, '|'),
m.genres = split(row.genres, '|')
RETURN
m.title AS title,
m.imdbId AS imdbId,
m.languages AS languages,
m.genres AS genres
LIMIT 5
| title | imdbId | languages | genres |
|---|---|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5 行 添加了 93 个节点,设置了 465 个属性,添加了 93 个标签 |
|||
有关更多 STRING 字符串操作函数,请参阅字符串函数。
建议
创建属性唯一性约束
在导入数据之前,务必创建属性唯一性约束,以避免重复或冲突的实体。如果源文件包含重复数据并且存在正确的约束,Cypher 将引发错误。
person_tmdbId,bio,born,bornIn,died,person_imdbId,name,person_poster,person_url
3,"Legendary Hollywood Icon Harrison Ford was born on July 13, 1942 in Chicago, Illinois. His family history includes a strong lineage of actors, radio personalities, and models. Harrison attended public high school in Park Ridge, Illinois where he was a member of the school Radio Station WMTH. Harrison worked as the lead voice for sports reporting at WMTH for several years. Acting wasn’t a major interest to Ford until his junior year at Ripon College when he first took an acting class...",1942-07-13,"Chicago, Illinois, USA",,148,Harrison Ford,https://image.tmdb.org/t/p/w440_and_h660_face/5M7oN3sznp99hWYQ9sX0xheswWX.jpg,https://themoviedb.org/person/3
...
CREATE CONSTRAINT Person_tmdbId IF NOT EXISTS
FOR (p:Person) REQUIRE p.tmdbId IS UNIQUE
Added 1 constraints
处理大量数据
当文件包含大量行(接近数十万或数百万行)时,LOAD CSV 可能会遇到内存问题。对于大文件,建议通过子句CALL {…} IN TRANSACTIONS将导入过程拆分为多个较轻的事务。
文件persons.csv包含一个标题行和总共 869 行。该示例以每 200 行一个事务的方式加载 name 和 born 列。
person_tmdbId,bio,born,bornIn,died,person_imdbId,name,person_poster,person_url
3,"Legendary Hollywood Icon Harrison Ford was born on July 13, 1942 in Chicago, Illinois. His family history includes a strong lineage of actors, radio personalities, and models. Harrison attended public high school in Park Ridge, Illinois where he was a member of the school Radio Station WMTH. Harrison worked as the lead voice for sports reporting at WMTH for several years. Acting wasn’t a major interest to Ford until his junior year at Ripon College when he first took an acting class...",1942-07-13,"Chicago, Illinois, USA",,148,Harrison Ford,https://image.tmdb.org/t/p/w440_and_h660_face/5M7oN3sznp99hWYQ9sX0xheswWX.jpg,https://themoviedb.org/person/3
...
下面的查询使用变量范围子句(在 Neo4j 5.23 中引入)将变量导入 CALL 子查询。如果您使用的是旧版 Neo4j,请改用导入 WITH 子句。 |
LOAD CSV WITH HEADERS FROM 'https://data.neo4j.com/importing-cypher/persons.csv' AS row
CALL (row) {
MERGE (p:Person {tmdbId: row.person_tmdbId})
SET p.name = row.name, p.born = row.born
} IN TRANSACTIONS OF 200 ROWS
Added 444 nodes, Set 1332 properties, Added 444 labels
如果发生错误,CALL {…} IN TRANSACTIONS 可能只导入部分 CSV 数据,因为事务是已提交的。例如,如果前 200 行没有错误,它们将被提交。如果接下来的 200 行包含导致错误的数据,则第二个事务将失败,但不会影响第一个事务。 |
LOAD CSV 和 Neo4j 函数
使用 linenumber() 访问行号
当 LOAD CSV 操作时,linenumber() 函数提供行号,如果在 LOAD CSV 上下文之外调用,则返回 null。
此函数的一个常见用例是为没有唯一列的 CSV 数据生成顺序的唯一 ID。
linenumber()1,ABBA,1992
2,Roxette,1986
3,Europe,1979
4,The Cardigans,1992
LOAD CSV FROM 'file:///artists.csv' AS row
RETURN linenumber() AS number, row
| number | row |
|---|---|
|
|
|
|
|
|
|
|
4 行 |
|
使用 file() 访问 CSV 文件路径
当 LOAD CSV 操作时,file() 函数提供文件的绝对路径,如果在 LOAD CSV 上下文之外调用,则返回 null。
file()1,ABBA,1992
2,Roxette,1986
3,Europe,1979
4,The Cardigans,1992
LOAD CSV FROM 'file:///artists.csv' AS row
RETURN DISTINCT file() AS path
| path |
|---|
|
file() 始终返回本地路径,即使在加载远程 CSV 文件时也是如此。对于远程资源,file() 返回其下载到的临时本地路径。 |
CSV 文件格式
CSV 文件格式和 LOAD CSV 的交互方式如下:
-
文件字符编码必须是 UTF-8。
-
行终止符取决于系统(Unix 为
\n,Windows 为\r\n)。 -
默认字段分隔符是
,。使用FIELDTERMINATOR选项可以更改它。 -
CSV 文件可能包含带引号的
STRING字符串值,LOAD CSV读取数据时会删除引号。 -
如果
dbms.import.csv.legacy_quote_escaping设置为默认值true,则\用作转义字符。 -
双引号必须在带引号的
STRING字符串中并进行转义,可以使用转义字符或第二个双引号。
标题
如果 CSV 文件以包含列名的标题行开头,则文件中的每个导入行都将作为映射而不是数组。
您必须通过在查询中添加 WITH HEADERS 来指示标题行的存在。然后,您可以通过其对应的列名访问特定字段。
Id,Name,Year
1,ABBA,1992
2,Roxette,1986
3,Europe,1979
4,The Cardigans,1992
LOAD CSV WITH HEADERS FROM 'file:///artists-with-headers.csv' AS row
MERGE (a:Artist {name: row.Name, year: toInteger(row.Year)})
RETURN
a.name AS name,
a.year AS year
| name | year |
|---|---|
|
|
|
|
|
|
|
|
4 行 添加了 4 个节点,设置了 8 个属性,添加了 4 个标签 |
|
"The Cardigans"
默认字段分隔符是 ,。使用 FIELDTERMINATOR 选项指定不同的字段分隔符。
, 作为字段分隔符的文件,并且您也没有指定自定义分隔符,LOAD CSV 会将该 CSV 文件解释为只有一列。; 作为字段分隔符导入 CSV1;ABBA;1992
2;Roxette;1986
3;Europe;1979
4;The Cardigans;1992
LOAD CSV FROM 'file:///artists-fieldterminator.csv' AS row FIELDTERMINATOR ';'
MERGE (:Artist {name: row[1], year: toInteger(row[2])})
Added 4 nodes, Set 8 properties, Added 4 labels
| artists-fieldterminator.csv |
如果您在 Unicode 字符的十六进制表示前加上 \u,则可以使用它作为字段分隔符。使用四位数字编写编码:例如,\u003B 等同于 ;(分号)。
-
CSV 文件中允许带引号的
STRING字符串值,当LOAD CSV读取数据时,引号会被去除。如果带引号的STRING值必须包含引号字符",有两种转义方法: -
双引号 — 使用另一个引号
"来转义引号(例如,STRING字符串The "Symbol"的 CSV 编码是"The ""Symbol""")。
\ — 如果配置设置 dbms.import.csv.legacy_quote_escaping 设置为 true(默认值),则 \ 用作引号的转义字符(例如,STRING 字符串 The "Symbol" 的 CSV 编码是 "The \"Symbol\"")。"1","The ""Symbol""","1992"
"2","The \"Symbol\"","1992"
LOAD CSV FROM 'file:///artists-with-escaped-quotes.csv' AS row
MERGE (a:Artist {id: toInteger(row[0]), name: row[1], year: toInteger(row[2])})
RETURN
a.id AS id,
a.name AS name,
a.year AS year,
size(a.name) AS size
| artists-with-escaped-quotes.csv | name | year | id |
|---|---|---|---|
|
|
|
|
|
|
|
|
'The "Symbol"' |
|||
添加了 2 个节点,设置了 6 个属性,添加了 2 个标签
请注意,name 是一个 STRING 字符串,因为它在输出中被引号包围。第三列将 STRING 字符串长度输出为 size。长度只计算外部引号之间的内容,不包括引号本身。
-
如果导入失败,需要检查一些元素以确保源文件未损坏。
-
不一致的标题 — CSV 标题可能与数据不一致。它可能缺失、列数过多或使用不同的分隔符。请验证标题与文件中的数据是否匹配。调整格式、分隔符或列。
-
多余或缺失的引号 — 非引号文本中间的独立双引号或单引号,或引号文本中未转义的引号都可能导致读取文件时出现问题。请转义或移除多余的引号。参阅引号转义。
-
特殊字符或换行符 — 处理文件中的特殊字符时,请确保它们被引用或将其移除。
-
不一致的换行符 — 确保文件中的换行符一致。
二进制零、BOM 字节顺序标记和其他非文本字符 — 异常字符或特定工具的格式有时在应用程序工具中是隐藏的,但在纯文本编辑器中会变得明显。如果您在文件中遇到这些类型的字符,请将其移除或使用 Cypher 的normalize 函数。
LOAD CSV 检查源文件,了解导入数据将具有的形式。// Assert correct line count
LOAD CSV FROM 'https://data.neo4j.com/importing-cypher/persons.csv' AS line
RETURN count(*);
| 示例 20. 断言正确的行数 |
|---|
|
count(*) |
// Check first 5 line-sample with header-mapping
LOAD CSV WITH HEADERS FROM 'https://data.neo4j.com/importing-cypher/persons.csv' AS line
RETURN line.person_tmdbId, line.name
LIMIT 5;
| 示例 21. 检查前五行(带标题采样) | line.person_tmdbId |
|---|---|
|
|
|
|
|
|
|
|
|
|
5 行 |
|
line.name
// Clear data
MATCH (n) DETACH DELETE n;
// Create constraints
CREATE CONSTRAINT Person_tmdbId IF NOT EXISTS
FOR (p:Person) REQUIRE p.tmdbId IS UNIQUE;
CREATE CONSTRAINT Movie_movieId IF NOT EXISTS
FOR (m:Movie) REQUIRE m.movieId IS UNIQUE;
// Create person nodes
LOAD CSV WITH HEADERS FROM 'https://data.neo4j.com/importing-cypher/persons.csv' AS row
MERGE (p:Person {tmdbId: toInteger(row.person_tmdbId)})
SET p.name = row.name, p.born = date(row.born);
// Create movie nodes
LOAD CSV WITH HEADERS FROM 'https://data.neo4j.com/importing-cypher/movies.csv' AS row
MERGE (m:Movie {id: toInteger(row.movieId)})
SET
m.title = row.title,
m.imdbId = toInteger(row.movie_imdbId),
m.languages = split(row.languages, '|'),
m.genres = split(row.genres, '|');
// Create relationships
LOAD CSV WITH HEADERS FROM 'https://data.neo4j.com/importing-cypher/acted_in.csv' AS row
MATCH (p:Person {tmdbId: toInteger(row.person_tmdbId)})
MATCH (m:Movie {id: toInteger(row.movieId)})
MERGE (p)-[r:ACTED_IN]->(m)
SET r.role = row.role;
// Set additional node label
MATCH (p:Person)-[:ACTED_IN]->()
WITH DISTINCT p
SET p:Actor;
Added 1 constraints
Added 1 constraints
Added 444 nodes, Set 1332 properties, Added 444 labels
Added 93 nodes, Set 465 properties, Added 93 labels
Created 372 relationships, Set 372 properties
Added 353 labels
| 擦除当前数据库并导入完整的电影数据集 |
随着数据量的增加,更有效的方法是先创建所有节点,然后通过第二次处理添加关系。
-
还有其他一些工具可以将 CSV 数据导入 Neo4j。
-
neo4j-admin database import命令是导入大型 CSV 文件最有效的方式。 -
使用语言库来解析 CSV 数据并针对 Neo4j 数据库运行创建 Cypher 查询。作为扩展库创建,旨在为开发人员提供通用过程和函数。该库对于复杂转换和数据操作特别有用。有用的过程包括 apoc.load.jdbc、apoc.load.json 等。
-
这款ETL 工具:允许从关系数据库中提取模式并将其转换为图模型。然后它负责将数据导入 Neo4j。