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
导入本地文件Aura 不支持
您可以将 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 会在内部采取措施,在限制范围内增强这些请求的安全性。然而,这意味着除非您在配置设置 |
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 导入企业版Aura 不可用
您可以从多种不同的云存储中导入数据
有关如何设置云存储访问权限的信息,请参阅 操作手册 → 从云存储加载转储。
从 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 关系的人添加了额外的 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 值的几种选项。
此示例中的查询使用 FILTER(在 Neo4j 2025.06 中引入)来代替 WITH * WHERE <predicate>。 |
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
FILTER row.Id IS NOT NULL
MERGE (c:Company {id: row.Id})
null 值提供默认值LOAD CSV WITH HEADERS FROM 'file:///companies.csv' AS row
FILTER 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
FILTER 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
| 标题 | 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
...
下面的查询使用 变量作用域子句 将变量导入到 CALL 子查询中。 |
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() 访问行号
linenumber() 函数提供 LOAD CSV 正在操作的行号,如果是在 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 文件路径
file() 函数提供 LOAD CSV 正在操作的文件的绝对路径,如果是在 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 |
|---|
|
即使在加载远程 CSV 文件时,file() 也总是返回本地路径。对于远程资源,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 个标签 |
|
字段分隔符
默认字段分隔符是 ,。使用 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
如果您在前面加上 \u,则可以使用字段分隔符的 unicode 字符的十六进制表示。使用四位数字编写编码:例如,\u003B 等同于 ;(分号)。 |
引号转义
CSV 文件中允许带引号的 STRING 值,当 LOAD CSV 读取数据时,引号会被丢弃。如果带引号的 STRING 值必须包含引号字符 ",有两种方法可以转义它们
-
双引号 — 使用另一个引号
"转义引号(例如,STRINGThe "Symbol"的 CSV 编码是"The ""Symbol""")。 -
反斜杠前缀
\— 如果配置设置dbms.import.csv.legacy_quote_escaping设置为true(默认值),则\用作引号的转义字符(例如,STRINGThe "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
| id | 名称 (name) | year | size |
|---|---|---|---|
|
|
|
|
|
|
|
|
添加了 2 个节点,设置了 6 个属性,添加了 2 个标签 |
|||
请注意,name 是一个 STRING,因为它在输出中被引号包围。第三列输出 STRING 长度作为 size。长度仅计算外部引号之间的内容,而不计算引号本身。
检查源数据质量
如果导入失败,请检查一些元素以确保源文件没有损坏。
-
不一致的标题 — CSV 标题可能与数据不一致。它可能缺失、列数过多或分隔符不同。验证标题是否与文件中的数据匹配。调整格式、分隔符或列。
-
额外或缺失的引号 — 非引号文本中间的独立双引号或单引号,或带引号文本中未转义的引号可能会导致读取文件时出现问题。转义或删除杂乱的引号。请参阅 引号转义。
-
特殊字符或换行符 — 处理文件中的特殊字符时,确保它们被引号引起来或删除它们。
-
不一致的换行符 — 确保整个文件中的换行符一致。
-
二进制零、BOM 字节顺序标记和其他非文本字符 — 不寻常的字符或特定工具的格式有时在应用程序工具中是隐藏的,但在纯文本编辑器中会显现出来。如果您在文件中遇到这些类型的字符,请删除它们或使用 Cypher 的 规范化函数。
在导入前检查源文件
在将数据导入数据库之前,您可以使用 LOAD CSV 检查源文件,并了解导入数据将具有的形式。
// Assert correct line count
LOAD CSV FROM 'https://data.neo4j.com/importing-cypher/persons.csv' AS line
RETURN count(*);
| count(*) |
|---|
|
1 行 |
// 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;
| line.person_tmdbId | line.name |
|---|---|
|
|
|
|
|
|
|
|
|
|
5 行 |
|
示例
// 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。
-
Kettle 导入工具 映射并执行数据处理流程的步骤,对于非常大的数据集非常有效,尤其是如果您已经熟悉使用此工具。