apoc.import.csv
|
从本地文件导入需要将 `apoc.import.file.enabled=true` 设置在 apoc.conf 中。Aura 不支持此功能。因此,Aura 实例仅限于导入公共托管文件。 |
语法 |
|
||
描述 |
从提供的 CSV 文件中导入具有给定标签和类型的 `NODE` 和 `RELATIONSHIP` 值。 |
||
输入参数 |
名称 |
类型 |
描述 |
|
|
映射值列表,指定从何处导入节点值;`{ fileName :: STRING, data :: BYTEARRAY, labels :: LIST<STRING> }`。 |
|
|
|
映射值列表,指定从何处导入关系值:`{ fileName :: STRING, data :: BYTEARRAY, type :: STRING }`。 |
|
|
|
|
|
返回参数 |
名称 |
类型 |
描述 |
|
|
导入数据的文件名。 |
|
|
|
导入数据的来源:“file”、“binary”或“file/binary”。 |
|
|
|
文件格式:["csv", "graphml", "json"]。 |
|
|
|
导入的节点数量。 |
|
|
|
导入的关系数量。 |
|
|
|
导入的属性数量。 |
|
|
|
导入的持续时间。 |
|
|
|
返回的行数。 |
|
|
|
导入运行时批次的大小。 |
|
|
|
导入运行时批次的数量。 |
|
|
|
导入是否成功运行。 |
|
|
|
导入返回的数据。 |
|
配置参数
此过程支持以下配置参数
| 名称 | 类型 | 默认值 | 描述 | 导入工具对应项 |
|---|---|---|---|---|
|
|
, |
列之间的分隔符 |
|
|
|
; |
数组中的分隔符 |
|
|
|
false |
对于重复节点,只加载第一个并跳过其余节点(true)或导入失败(false) |
|
|
|
" |
引用字符 |
|
|
|
true |
将 ID 视为字符串 |
|
|
|
1 |
要跳过的行(包括标题) |
N/A |
|
|
false |
如果为 true,则忽略空字符串属性 |
N/A |
|
|
false |
如果为 true,则忽略包含单个空字符串的数组属性,类似于导入工具 |
N/A |
|
|
|
允许获取二进制数据,可以是未压缩(值:`NONE`)或已压缩(其他值)。 |
N/A |
|
|
'UTF-8' |
当前使用的 JDK 中扩展 java.nio.Charset 的字符集名称。例如: |
|
|
|
2000 |
处理完指定行数后提交并继续 |
N/A |
使用 Cypher 加载 CSV 文件
Cypher 支持将数据从 CSV 文件加载到 Neo4j 数据库中。
LOAD CSV 示例LOAD CSV WITH HEADERS FROM 'file:///persons.csv' AS line
RETURN line.id, line.name
有关更多信息,请参阅Cypher 手册 → LOAD CSV。
使用示例
此过程导入符合 Neo4j 导入工具头格式的 CSV 文件。
导入节点
以下 CSV 文件包含两个人
id:ID,name:STRING
1,John
2,Jane
本示例假设文件放置在 Neo4j 实例的 import 目录中。
我们可以使用 APOC 和 Cypher 创建两个设置了 Person 属性的 name 节点
CALL apoc.import.csv([{fileName: 'file:/persons.csv', labels: ['Person']}], [], {});
YIELD nodes
RETURN nodes
LOAD CSV WITH HEADERS FROM 'file:///persons.csv' AS line
CREATE (:Person { id: line['id:ID'], name: line['name:STRING'] })
RETURN count(*) AS nodes
| nodes | |
|---|---|
2 |
我们可以通过运行以下查询来检查已导入的内容
MATCH (p:Person)
RETURN p
| p |
|---|
(:Person {name: "John", id: "1"}) |
(:Person {name: "Jane", id: "2"}) |
节点和关系
以下文件包含 CSV 格式的 NODE 和 RELATIONSHIP 值
:ID|name:STRING|speaks:STRING[]
1|John|en,fr
2|Jane|en,de
:START_ID|:END_ID|since:INT
1|2|2016
我们将导入两个 Person 节点和一个 KNOWS 关系(设置了 since 属性的值)。字段终止符和数组分隔符已从默认值更改,并且 CSV 使用数字 ID。
CALL apoc.import.csv(
[{fileName: 'file:/people-nodes.csv', labels: ['Person']}],
[{fileName: 'file:/knows-rels.csv', type: 'KNOWS'}],
{delimiter: '|', arrayDelimiter: ',', stringIds: false}
);
LOAD CSV WITH HEADERS FROM 'file:///old.csv' AS line FIELDTERMINATOR '|'
CREATE (p:Person { id: line[':ID'], speaks: split(line['speaks:STRING[]'], ','), name: line['name:STRING'] })
WITH count(*) AS nodes
LOAD CSV WITH HEADERS FROM 'file:///users.csv' AS line FIELDTERMINATOR '|'
MATCH (a:Person {id: line[':START_ID']}), (b:Person {id: line[':END_ID']})
CREATE (a)-[:KNOWS { since: toInteger(line['since:INT']) }]->(b)
RETURN nodes, count(*) AS relationships
| nodes | relationships | |
|---|---|---|
2 |
1 |
我们可以通过运行以下查询来检查已导入的内容
MATCH path = (p1:Person)-[:KNOWS]->(p2:Person)
RETURN path
| path |
|---|
(:Person {name: "John", speaks: ["en", "fr"], _csv_id: 1})-[:KNOWS {since: 2016}]→(:Person {name: "Jane", speaks: ["en", "de"], _csv_id: 2}) |
二进制文件
您还可以从二进制 byte[] 文件(未压缩,默认值为 NONE)或压缩文件(允许的压缩算法有:GZIP、BZIP2、DEFLATE、BLOCK_LZ4、FRAMED_SNAPPY)导入文件。请注意,在这种情况下,对于 relations 和 nodes 参数映射,文件的键是 data 而不是 fileName,即
CALL apoc.import.csv([{data: `binaryGzipByteArray`, labels: ['Person']}], [{data: `binaryGzipByteArray`, type: 'KNOWS'}], {compression: 'GZIP'})
或
CALL apoc.import.csv([{data: `binaryFileNotCompressed`, labels: ['Person']}], [{data: `binaryFileNotCompressed`, type: 'KNOWS'}], {compression: 'NONE'})
例如,这与 apoc.util.compress 函数配合得很好
WITH apoc.util.compress(':ID|firstname:STRING|lastname:IGNORE|age:INT\n1|John|Doe|25\n2|Jane|Doe|26', {compression: 'DEFLATE'}) AS nodeCsv
WITH apoc.util.compress(':START_ID|:END_ID|prop1:IGNORE|prop2:INT\n1|2|a|3\n2|1|b|6', {compression: 'DEFLATE'}) AS relCsv, nodeCsv
CALL apoc.import.csv([{data: nodeCsv, labels: ['Person']}], [{data: relCsv, type: 'KNOWS'}], {delimiter: '|', compression: 'DEFLATE'})
YIELD source, format, nodes, relationships, properties
RETURN source, format, nodes, relationships, properties
| source | format | nodes | relationships | properties |
|---|---|---|---|---|
"binary" |
"csv" |
2 |
2 |
8 |
属性
对于属性,字段的 <name> 部分指定属性键,而 <field_type> 部分(在 : 之后)分配数据类型(见下文)。节点数据文件和关系数据文件中都可以包含属性。
使用 int、long、float、double、boolean、byte、short、char、string、point、date、localtime、time、localdatetime、datetime 和 duration 中的一个来指定属性的数据类型。如果没有给定数据类型,则默认为字符串。要定义数组类型,请在类型后面附加 []。例如
:ID,name,joined:date,active:boolean,points:int
user01,Joe Soap,2017-05-05,true,10
user02,Jane Doe,2017-08-21,true,15
user03,Moe Know,2018-02-17,false,7
点
点使用 Cypher 的映射语法指定。该映射允许使用与 Point 函数输入相同的键。头中的点数据类型可以使用一个 MAP 默认值进行修改,该默认值用于该列的所有值,例如 point{crs: 'WGS-84'}。以这种方式指定头允许数据文件中的值位置包含不完整的映射。可选地,数据文件中的值可以覆盖头中的默认值。
:ID,name,location:point{crs:WGS-84}
city01,"Malmö","{latitude:55.6121514, longitude:12.9950357}"
city02,"London","{y:51.507222, x:-0.1275}"
city03,"San Mateo","{latitude:37.554167, longitude:-122.313056, height: 100, crs:'WGS-84-3D'}"
在上面的 CSV 中
-
第一个城市的地理位置使用
latitude和longitude定义,与头中定义的坐标系使用方式一致。 -
第二个城市改用
x和y。这通常会导致一个点使用笛卡尔坐标系。由于头中定义了 crs:WGS-84,因此将使用该坐标系。 -
第三个城市覆盖了头中定义的坐标系,并将其明确设置为 WGS-84-3D。
时间
所有时间数据类型的格式必须按照 时间瞬时语法和 持续时间语法 中的描述进行定义。时间类型中的两种,Time 和 DateTime,都接受一个时区参数,该参数可能在数据文件中的所有值或许多值之间是通用的。因此,可以在头中为 Time 和 DateTime 值指定一个默认时区,例如:time{timezone:+02:00} 和 datetime{timezone:Europe/Stockholm}。
:ID,date1:datetime{timezone:Europe/Stockholm},date2:datetime
1,2018-05-10T10:30,2018-05-10T12:30
2,2018-05-10T10:30[Europe/Berlin],2018-05-10T12:30[Europe/Berlin]
在上面的 CSV 中
-
第一行有两个未指定显式时区的值。
date1的值将使用头中为该字段指定的Europe/Stockholm时区。date2的值将使用数据库配置的默认时区。 -
在第二行中,
date1和date2都将时区明确设置为Europe/Berlin。这会覆盖 date1 的头定义,以及数据库配置的默认时区。