apoc.import.csv过程
|
从本地文件导入数据需要在 apoc.conf 中设置 |
语法 |
|
||
描述 |
根据提供的 CSV 文件中给定的标签和类型,导入 |
||
输入参数 |
名称 |
类型 |
描述 |
|
|
包含节点值导入位置的 Map 列表; |
|
|
|
包含关系值导入位置的 Map 列表: |
|
|
|
|
|
返回参数 |
名称 |
类型 |
描述 |
|
|
导入数据所用的文件名。 |
|
|
|
导入数据的来源:"file"(文件)、"binary"(二进制)或 "file/binary"。 |
|
|
|
文件格式:["csv", "graphml", "json"]。 |
|
|
|
导入的节点数量。 |
|
|
|
导入的关系数量。 |
|
|
|
导入的属性数量。 |
|
|
|
导入持续时间。 |
|
|
|
返回的行数。 |
|
|
|
导入过程中使用的批处理大小。 |
|
|
|
导入过程中执行的批次数。 |
|
|
|
导入是否成功完成。 |
|
|
|
导入返回的数据。 |
|
配置参数
此过程支持以下配置参数
| 名称 | 类型 | 默认 | 描述 | 导入工具对应项 |
|---|---|---|---|---|
|
|
, |
列之间的分隔符 |
|
|
|
; |
数组中的分隔符 |
|
|
|
false |
对于重复节点,仅加载第一个并跳过其余部分 (true),或导致导入失败 (false) |
|
|
|
" |
引用字符 |
|
|
|
true |
将 ID 视为字符串 |
|
|
|
1 |
要跳过的行数(包含标题行) |
不适用 |
|
|
false |
如果为 true,则忽略空白字符串属性 |
不适用 |
|
|
false |
如果为 true,则像导入工具一样忽略包含单个空字符串的数组属性 |
不适用 |
|
|
|
允许接收二进制数据,可以是不压缩的 (值: |
不适用 |
|
|
'UTF-8' |
当前 JDK 中扩展 java.nio.Charset 的字符集名称。例如: |
|
|
|
2000 |
处理完指定行数后提交并继续 |
不适用 |
使用 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 创建两个设置了 name 属性的 Person 节点
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
| 节点 | |
|---|---|
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
| 节点 | 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 | 节点 | relationships | 属性 |
|---|---|---|---|---|
"binary" |
"csv" |
2 |
2 |
8 |
属性
对于属性,字段的 <name> 部分指定属性键,而 <field_type> 部分(在 : 之后)指定数据类型(见下文)。您可以在节点数据文件和关系数据文件中使用属性。
使用 int, long, float, double, boolean, byte, short, char, string, point, date, localtime, time, localdatetime, datetime 和 duration 中的一种来指定属性的数据类型。如果未提供数据类型,则默认为 string。要定义数组类型,请在类型后附加 []。例如:
: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
Point(点)
点使用 Cypher 的 Map 语法指定。该 Map 允许使用与 Point 函数输入相同的键。标题中的点数据类型可以使用一个默认值的 MAP 进行修补,这些默认值将用于该列的所有值,例如 point{crs: 'WGS-84'}。以这种方式指定标题允许您在数据文件的值位置使用不完整的 Map。可选地,数据文件中的值可以覆盖标题中的默认值。
: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。
Temporal(时间)
所有时间数据类型的格式必须按照 Temporal instants(时间瞬间)语法 和 Durations(持续时间)语法进行定义。两种时间类型 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 的标题定义,以及数据库配置的默认时区。