导出为 JSON

导出 JSON 过程将数据导出为 JavaScript 可视化工具支持的格式。我们也可能希望将数据导出为 JSON 格式,以便导入其他工具或用于常规查询结果共享。本节中描述的过程支持导出到文件或作为流(Stream)导出。

使用的格式是 jsonlines 或 JSONL,这是一种流式格式,每行包含一个 JSON 对象,在本例中为节点或关系。

可用过程

下表描述了可用的过程:

限定名称 类型

apoc.export.json.all
apoc.export.json.all(file STRING, config MAP<STRING, ANY>) - 将整个数据库导出到提供的 JSON 文件中。

过程

apoc.export.json.data
apoc.export.json.data(nodes LIST<NODE>, rels LIST<RELATIONSHIP>, file STRING, config MAP<STRING, ANY>) - 将给定的 NODERELATIONSHIP 值导出到提供的 JSON 文件中。

过程

apoc.export.json.graph
apoc.export.json.graph(graph MAP<STRING, ANY>, file STRING , config MAP<STRING, ANY>) - 将给定的图形导出到提供的 JSON 文件中。

过程

apoc.export.json.query
apoc.export.json.query(statement STRING, file STRING, config MAP<STRING, ANY>) - 将 Cypher 语句的结果导出到提供的 JSON 文件中。

过程

表 1. 配置
名称 (name) type 默认 description(描述)

writeNodeProperties

布尔值 (BOOLEAN)

true

如果为 true,则也导出属性。

stream

布尔值 (BOOLEAN)

false

将 json 直接流式传输到客户端的 data 字段中

jsonFormat

enum[JSON_LINES, ARRAY_JSON, JSON, JSON_ID_AS_KEYS]

JSON_LINES

导出 json 的格式

表 2. jsonFormat 类型
名称 (name) description(描述)

JSON_LINES

数据将导出为 JSON lines

ARRAY_JSON

数据将导出为 json 数组:[{"type":"node","id":"2","labels":["User"],"properties":{"age":12}},…​]

JSON

数据将导出为包含两个(数组)字段 nodesrels 的 json:{"nodes":[{"type":"node","id":"2","labels":["User"],"properties":{…​}},…​],"rels":[{"id":"0","type":"relationship","label":"KNOWS","properties":{"since":1993},"start":{"id":"0","labels":["User"]},"end":{"id":"1","labels":["User"]}},…​]}

JSON_ID_AS_KEYS

数据将导出为包含两个(映射/map)字段 nodesrels 的 json,其中键是 neo4j 内部 id,值是图实体值:{"nodes":{"0":{"type":"node","id":"0","labels":["User"],"properties":{…​},"1":{…​},"2":{…​},"rels":{"0":{"id":"0","type":"relationship","label":"KNOWS","properties":{…​},"start":{"id":"0","labels":["User"]},"end":{"id":"1","labels":["User"]}}}}

导出的标签按字母顺序排列。labels() 函数的输出不是排序的,请将其与 apoc.coll.sort() 结合使用。

导出到文件

默认情况下,导出到文件系统是被禁用的。我们可以通过在 apoc.conf 中设置以下属性来启用它:

apoc.conf
apoc.export.file.enabled=true

有关访问 apoc.conf 的更多信息,请参阅配置选项章节。

如果我们尝试在未先设置此属性的情况下使用任何导出过程,我们将收到以下错误消息:

Failed to invoke procedure: Caused by: java.lang.RuntimeException: Export to files not enabled, please set apoc.export.file.enabled=true in your apoc.conf. Otherwise, if you are running in a cloud environment without filesystem access, use the {stream:true} config and null as a 'file' parameter to stream the export back to your client.

导出文件被写入 import 目录,该目录由 server.directories.import 属性定义。这意味着我们提供的任何文件路径都是相对于此目录的。如果我们尝试写入绝对路径(例如 /tmp/filename),我们将收到类似于以下内容的错误消息:

Failed to invoke procedure: Caused by: java.io.FileNotFoundException: /path/to/neo4j/import/tmp/fileName (No such file or directory)

我们可以通过在 apoc.conf 中设置以下属性来允许写入文件系统上的任何位置:

apoc.conf
apoc.import.file.use_neo4j_config=false

Neo4j 现在将能够写入文件系统上的任何位置,因此在设置此属性之前,请确保这是您的意图。

导出流

如果我们不想导出到文件,可以通过将文件名设置为 null 并提供 stream:true 配置,将结果流式传输回 data 列。

示例

本节包含展示如何使用 JSON 导出过程的示例。这些示例基于一个人员数据集,可以通过运行以下 Cypher 查询进行导入

CREATE (a:User {
    name:'Adam', age:42, male:true, kids:['Sam','Anna','Grace'],
    born:localdatetime('2015185T19:32:24'),
    place:point({latitude: 13.1, longitude: 33.46789})
})
CREATE (b:User {name:'Jim', age:42})
CREATE (c:User {age:12})

CREATE (a)-[:KNOWS {since: 1993}]->(b)

下方的 Neo4j Browser 可视化显示了导入的图

请注意,为了正确执行 Point 序列化,不建议导出坐标为 x,y 且 crs: 'wgs-84' 的点,例如 point({x: 56.7, y: 12.78, crs: 'wgs-84'})。否则,该点将以经度和纬度(以及高度)而不是 x 和 y(以及 z)进行导出。

export json

将整个数据库导出为 JSON

apoc.export.json.all 过程将整个数据库导出为 JSON 文件或作为流导出。

以下查询将整个数据库导出到 all.json 文件
CALL apoc.export.json.all("all.json",{useTypes:true})
表 3. 结果
file source format 节点 relationships 属性 time rows batchSize batches done data

"all.json"

"database: nodes(3), rels(1)"

"json"

3

1

10

7

0

-1

0

TRUE

NULL

all.json 的内容如下所示

all.json
{"type":"node","id":"0","labels":["User"],"properties":{"born":"2015-07-04T19:32:24","name":"Adam","place":{"crs":"wgs-84","latitude":13.1,"longitude":33.46789,"height":null},"age":42,"male":true,"kids":["Sam","Anna","Grace"]}}
{"type":"node","id":"1","labels":["User"],"properties":{"name":"Jim","age":42}}
{"type":"node","id":"2","labels":["User"],"properties":{"age":12}}
{"id":"0","type":"relationship","label":"KNOWS","properties":{"bffSince":"P5M1DT12H","since":1993},"start":{"id":"0","labels":["User"],"properties":{"born":"2015-07-04T19:32:24","name":"Adam","place":{"crs":"wgs-84","latitude":13.1,"longitude":33.46789,"height":null},"age":42,"male":true,"kids":["Sam","Anna","Grace"]}},"end":{"id":"1","labels":["User"],"properties":{"name":"Jim","age":42}}}
以下查询在 data 列中返回整个数据库的流:
CALL apoc.export.json.all(null,{useTypes:true, stream: true})
YIELD file, nodes, relationships, properties, data
RETURN file, nodes, relationships, properties, data
表 4. 结果
file 节点 relationships 属性 data

NULL

3

1

10

"{\"type\":\"node\",\"id\":\"0\",\"labels\":[\"User\"],\"properties\":{\"born\":\"2015-07-04T19:32:24\",\"name\":\"Adam\",\"place\":{\"crs\":\"wgs-84\",\"latitude\":13.1,\"longitude\":33.46789,\"height\":null},\"age\":42,\"male\":true,\"kids\":[\"Sam\",\"Anna\",\"Grace\"]}} {\"type\":\"node\",\"id\":\"1\",\"labels\":[\"User\"],\"properties\":{\"name\":\"Jim\",\"age\":42}} {\"type\":\"node\",\"id\":\"2\",\"labels\":[\"User\"],\"properties\":{\"age\":12}} {\"id\":\"50000\",\"type\":\"relationship\",\"label\":\"KNOWS\",\"properties\":{\"since\":1993},\"start\":{\"id\":\"0\",\"labels\":[\"User\"]},\"end\":{\"id\":\"1\",\"labels\":[\"User\"]}}"

将指定的节点和关系导出为 JSON

apoc.export.json.data 过程将指定的节点和关系导出为 JSON 文件或作为流导出。

以下查询将所有 KNOWS 关系和 User 节点导出到 knows.json 文件
MATCH (nod:User)
MATCH ()-[rels:KNOWS]->()
WITH collect(nod) as a, collect(rels) as b
CALL apoc.export.json.data(a, b, "knows.json", null)
YIELD file, source, format, nodes, relationships, properties, time, rows, batchSize, batches, done, data
RETURN file, source, format, nodes, relationships, properties, time, rows, batchSize, batches, done, data
表 5. 结果
file source format 节点 relationships 属性 time rows batchSize batches done data

"knows.json"

"data: nodes(3), rels(3)"

"json"

3

1

10

1

0

-1

0

TRUE

NULL

knows.json 的内容如下所示

knows.json
{"type":"node","id":"0","labels":["User"],"properties":{"born":"2015-07-04T19:32:24","name":"Adam","place":{"crs":"wgs-84","latitude":13.1,"longitude":33.46789,"height":null},"age":42,"male":true,"kids":["Sam","Anna","Grace"]}}
{"type":"node","id":"1","labels":["User"],"properties":{"name":"Jim","age":42}}
{"type":"node","id":"2","labels":["User"],"properties":{"age":12}}
{"id":"0","type":"relationship","label":"KNOWS","properties":{"bffSince":"P5M1DT12H","since":1993},"start":{"id":"0","labels":["User"],"properties":{"born":"2015-07-04T19:32:24","name":"Adam","place":{"crs":"wgs-84","latitude":13.1,"longitude":33.46789,"height":null},"age":42,"male":true,"kids":["Sam","Anna","Grace"]}},"end":{"id":"1","labels":["User"],"properties":{"name":"Jim","age":42}}}
以下查询返回一个 data 列中包含所有 KNOWS 关系和 User 节点的流
MATCH (nod:User)
MATCH ()-[rels:KNOWS]->()
WITH collect(nod) as a, collect(rels) as b
CALL apoc.export.json.data(a, b, null, {stream: true})
YIELD file, nodes, relationships, properties, data
RETURN file, nodes, relationships, properties, data
表 6. 结果
file 节点 relationships 属性 data

NULL

3

1

10

"{\"type\":\"node\",\"id\":\"0\",\"labels\":[\"User\"],\"properties\":{\"born\":\"2015-07-04T19:32:24\",\"name\":\"Adam\",\"place\":{\"crs\":\"wgs-84\",\"latitude\":13.1,\"longitude\":33.46789 ,\"height\":null},\"age\":42,\"male\":true,\"kids\":[\"Sam\",\"Anna\",\"Grace\"]}} {\"type\":\"node\",\"id\":\"1\",\"labels\":[\"User\"],\"properties\":{\"name\":\"Jim\",\"age\":42}} {\"type\":\"node\",\"id\":\"2\",\"labels\":[\"User\"],\"properties\":{\"age\":12}} {\"id\":\"50000\",\"type\":\"rel

将 Cypher 查询结果导出为 JSON

apoc.export.json.query 过程将 Cypher 查询结果导出为 JSON 文件或作为流导出。

以下查询将所有 age 属性大于 10User 节点导出到 users-age.json 文件
CALL apoc.export.json.query(
    "MATCH (u:User) WHERE u.age > $age return u",
    "users-age.json",
    {params:{age:15}}
)
表 7. 结果
file source format 节点 relationships 属性 time rows batchSize batches done data

"users-age.json"

"statement: cols(1)"

"json"

2

0

8

3

2

-1

0

TRUE

NULL

users-age.json 的内容如下所示

users-age.json
{"u":{"type":"node","id":"0","labels":["User"],"properties":{"born":"2015-07-04T19:32:24","name":"Adam","place":{"crs":"wgs-84","latitude":13.1,"longitude":33.46789,"height":null},"age":42,"male":true,"kids":["Sam","Anna","Grace"]}}}
{"u":{"type":"node","id":"1","labels":["User"],"properties":{"name":"Jim","age":42}}}
{"u":{"type":"node","id":"2","labels":["User"],"properties":{"age":12}}}
以下查询将 age 属性大于 10User 节点流返回到 data
CALL apoc.export.json.query(
    "MATCH (u:User) WHERE u.age > $age return u",
    null,
    {params:{age:15}, stream: true}
)
YIELD file, nodes, relationships, properties, data
RETURN file, nodes, relationships, properties, data
表 8. 结果
file 节点 relationships 属性 data

NULL

2

0

8

"{\"u\":{\"type\":\"node\",\"id\":\"0\",\"labels\":[\"User\"],\"properties\":{\"born\":\"2015-07-04T19:32:24\",\"name\":\"Adam\",\"place\":{\"crs\":\"wgs-84\",\"latitude\":13.1,\"longitude\":33.46789,\"height\":null},\"age\":42,\"male\":true,\"kids\":[\"Sam\",\"Anna\",\"Grace\"]}}} {\"u\":{\"type\":\"node\",\"id\":\"1\",\"labels\":[\"User\"],\"properties\":{\"name\":\"Jim\",\"age\":42}}}"

以下查询将复杂的 Cypher 映射结构导出到 complex-cypher-structure.json 文件
WITH "RETURN {
	value:1,
    data:[
    	10, 'car', null,
        point({ longitude: 56.7, latitude: 12.78 }),
        point({ longitude: 56.7, latitude: 12.78, height: 8 }),
        point({ x: 2.3, y: 4.5 }),
        point({ x: 2.3, y: 4.5, z: 2 }),
        date('2018-10-10'),
        datetime('2018-10-18T14:21:40.004Z'),
        localdatetime({ year:1984, week:10, dayOfWeek:3, hour:12, minute:31, second:14, millisecond: 645 }),
        {x:1, y:[1,2,3,{age:10}]}
    ]
} as key" AS query
CALL apoc.export.json.query(query, "complex-cypher-structure.json")
YIELD file, source, format, nodes, relationships, properties, time, rows, batchSize, batches, done, data
RETURN file, source, format, nodes, relationships, properties, time, rows, batchSize, batches, done, data
表 9. 结果
file source format 节点 relationships 属性 time rows batchSize batches done data

"complex-cypher-structure.json"

"statement: cols(1)"

"json"

0

0

16

2

1

-1

0

TRUE

NULL

complex-cypher-structure.json 的内容如下所示

complex-cypher-structure.json
{"key":{"data":[10,"car",null,{"crs":"wgs-84","latitude":12.78,"longitude":56.7,"height":null},{"crs":"wgs-84-3d","latitude":12.78,"longitude":56.7,"height":8.0},{"crs":"cartesian","x":2.3,"y":4.5,"z":null},{"crs":"cartesian-3d","x":2.3,"y":4.5,"z":2.0},"2018-10-10","2018-10-18T14:21:40.004Z","1984-03-07T12:31:14.645",{"x":1,"y":[1,2,3,{"age":10}]}],"value":1}}
以下查询将 age 属性大于 10User 节点列表导出到 users-list.json 文件
CALL apoc.export.json.query(
    "MATCH (u:User) RETURN COLLECT(u) as list",
    "users-list.json",
    {params:{age:10}}
)
表 10. 结果
file source format 节点 relationships 属性 time rows batchSize batches done data

"users-list.json"

"statement: cols(1)"

"json"

3

0

9

1

1

-1

0

TRUE

NULL

users-list.json 的内容如下所示

users-list.json
{"list":[{"type":"node","id":"0","labels":["User"],"properties":{"born":"2015-07-04T19:32:24","name":"Adam","place":{"crs":"wgs-84","latitude":13.1,"longitude":33.46789,"height":null},"age":42,"male":true,"kids":["Sam","Anna","Grace"]}},{"type":"node","id":"1","labels":["User"],"properties":{"name":"Jim","age":42}},{"type":"node","id":"2","labels":["User"],"properties":{"age":12}}]}
以下查询将通过 KNOWS 关系连接的 User 节点的映射表示导出到 users-map.json 文件
CALL apoc.export.json.query(
    "MATCH (u:User)-[r:KNOWS]->(d:User) RETURN u {.*}, d {.*}, r {.*}",
    "users-map.json",
    {params:{age:10}}
)
表 11. 结果
file source format 节点 relationships 属性 time rows batchSize batches done data

"users-map.json"

"statement: cols(3)"

"json"

0

0

11

8

1

-1

0

TRUE

NULL

users-map.json 的内容如下所示

users-map.json
{"u":{"born":"2015-07-04T19:32:24","name":"Adam","place":{"crs":"wgs-84","latitude":13.1,"longitude":33.46789,"height":null},"age":42,"male":true,"kids":["Sam","Anna","Grace"]},"d":{"name":"Jim","age":42},"r":{"bffSince":"P5M1DT12H","since":1993}}

在此示例中,我们在 Cypher 语句中返回图实体时使用了 {.*} 语法。此语法返回图实体的映射表示,这意味着仅导出属性;标签和关系类型将被排除。

以下查询将所有 KNOWS 关系(包括起始节点、结束节点及其属性)导出到 knows-with-node-properties.json 文件
CALL apoc.export.json.query(
    "MATCH p = (u:User)-[rel:KNOWS]->(u2:User) RETURN rel",
    "knows-with-node-properties.json",
    {writeNodeProperties:true}
)
表 12. 结果
file source format 节点 relationships 属性 time rows batchSize batches done data

"knows-with-node-properties.json"

"statement: cols(1)"

"json"

0

1

1

20

2

-1

0

TRUE

NULL

knows-with-node-properties.json 的内容如下所示

knows-with-node-properties.json
{"rel":{"id":"0","type":"relationship","label":"KNOWS","properties":{"bffSince":"P5M1DT12H","since":1993},"start":{"id":"0","labels":["User"],"properties":{"born":"2015-07-04T19:32:24","name":"Adam","place":{"crs":"wgs-84","latitude":13.1,"longitude":33.46789,"height":null},"age":42,"male":true,"kids":["Sam","Anna","Grace"]}},"end":{"id":"1","labels":["User"],"properties":{"name":"Jim","age":42}}}}

您还可以压缩要导出的文件。请点击此处获取更多信息