3.3 数据导入与导出:三条路线的选型与实操


文档摘要

3.3 数据导入与导出:三条路线的选型与实操 本节摘要:把数据搬进图有三条主流路线:LOAD CSV 在线流式导入、neo4j-admin import 离线全量建库、驱动程序批量写入。三者的适用量级、时效性与调优手段完全不同。本节用同一份商品数据把三条路线各走一遍,给出选型表与高频坑位,最后交代导出的正确姿势。 图建好了,规模化的数据从哪来?本节的判断框架一句话:量级决定路线,时效决定事务粒度。 一、路线一:LOAD CSV——在线流式导入 LOAD CSV 直接在 Cypher 里读服务器上的 CSV,逐行流式处理,适合十万级以内、需要与其他写入同库共存的导入: 三个必须知道的细节:文件要放在导入目录并使用 前缀; 声明首行是列名,省略则从 取;

3.3 数据导入与导出:三条路线的选型与实操

本节摘要:把数据搬进图有三条主流路线:LOAD CSV 在线流式导入、neo4j-admin import 离线全量建库、驱动程序批量写入。三者的适用量级、时效性与调优手段完全不同。本节用同一份商品数据把三条路线各走一遍,给出选型表与高频坑位,最后交代导出的正确姿势。

图建好了,规模化的数据从哪来?本节的判断框架一句话:量级决定路线,时效决定事务粒度

一、路线一:LOAD CSV——在线流式导入

LOAD CSV 直接在 Cypher 里读服务器上的 CSV,逐行流式处理,适合十万级以内、需要与其他写入同库共存的导入:

// products.csv:sku,title,category,price LOAD CSV WITH HEADERS FROM 'file:///products.csv' AS row MERGE (p:Product {sku: row.sku}) ON CREATE SET p.title = row.title, p.price = toFloat(row.price) MERGE (c:Category {name: row.category}) MERGE (p)-[:IN_CATEGORY]->(c)
导入 5000 行后的验证查询: MATCH (p:Product) RETURN count(p) → 5000

三个必须知道的细节:文件要放在导入目录并使用 file:/// 前缀;WITH HEADERS 声明首行是列名,省略则从 row[0] 取;CSV 一切皆字符串,数值要显式 toFloat/toInteger,否则价格进来的是文本,后续聚合直接报错。

⚠️ 大文件给 LOAD CSV 配上 USING PERIODIC COMMIT(按批提交,防日志膨胀);同时给锚点属性建好索引,否则每行 MERGE 都是一次全量查找——这是 LOAD CSV "越导越慢"的经典原因。

二、路线二:neo4j-admin import——离线全量建库

百万到十亿级、可以停机初始化时,离线工具最快。它不走事务引擎,直接按存储格式生成库文件。要求两份输入:一份节点文件、一份关系文件,关系文件用 id 引用两端节点:

products_nodes.csv: :ID,sku,title,price,:LABEL 1,KB-87,机械键盘 87键,299,:Product 2,MS-03,无线鼠标,:Product purchases_rels.csv: :START_ID,:END_ID,qty,:TYPE 1,2,1,IN_CATEGORY
# 停机状态下执行(数据库目录内不能有运行中的实例) neo4j-admin database import full neo4j ^ --nodes=products_nodes.csv ^ --relationships=purchases_rels.csv ^ --overwrite-destination=true
Import summary: nodes: ........ 2,000,000 (3.2 s / 1M) relationships: 5,600,000 (4.1 s / 1M) 总耗时约 1 分 40 秒 -- 千万级数据分钟级完成

它的限制同样明确:只对空库或覆盖导入、不支持在导入中跑 Cypher 逻辑(数据清洗要在文件侧完成)、CSV 结构严格。

三、路线三:驱动批量写入——应用内持续同步

上游是消息队列或定时任务时,用驱动 + UNWIND 分批写:

rows = [{"sku": "KB-87", "title": "机械键盘", "price": 299.0}, ...] def batch_import(tx, batch): tx.run(""" UNWIND $rows AS row MERGE (p:Product {sku: row.sku}) ON CREATE SET p.title = row.title, p.price = row.price """, rows=batch) with driver.session(database="neo4j") as s: for i in range(0, len(rows), 500): # 每批 500 行 s.execute_write(batch_import, rows[i:i+500])

每批一个事务,批间自动重试(死锁与瞬时错误),速率可控、可断点续跑——这是三条路线里唯一适合"长期在线"的。

四、选型对账表

维度 LOAD CSV admin import 驱动批量
适用量级 ≤ 十万行 百万~十亿行 任意(速率可控)
时效 在线,与其他写入共存 离线,需停机 在线,常驻
数据清洗 Cypher 内可做 文件侧完成 应用代码完成
事务开销 逐行或周期提交 无(直接建文件) 按批提交
典型坑 无索引越导越慢 只能空库 批太大撑爆内存

图:三种导入路线的数据通路

图:三种导入路线的数据通路

五、导出:把图拿走

对称的三条路:小规模结果用 Cypher 导出 CSV/JSON;整库迁移用 neo4j-admin database dump 生成单文件备份包(3.4 节的备份用的就是它);持续同步到下游用驱动侧消费订阅或定期全量导出。

# 整库导出为可迁移的 dump 文件(停机或用企业版在线一致性备份) neo4j-admin database dump neo4j --to-path=D:/backup
neo4j.dump 已生成 → 可用 load 命令在任何同版本实例上恢复

六、导入前后的校验清单

数据搬进图不算完,"搬对"才算完:

导入前: 锚点索引是否已建(LOAD CSV 路线) CSV 编码与转义是否统一(UTF-8,含引号字段) 导入后: 节点/关系计数与源文件行数对账 抽查 20 条:属性类型正确(数字不是字符串) 孤儿关系检查:MATCH ()-[r]->() 是否有意外的悬空语义

计数对账一行搞定:MATCH (n:Product) RETURN count(n) 与源行数核对。数字对不上时,多半是 CSV 里重复键被 MERGE 吞了——按设计不该是错误,但得知道吞了多少。

本节要点回顾

  • 量级定路线:十万内 LOAD CSV,离线大库 admin import,在线持续驱动批量;
  • CSV 一切皆字符串,数值必须显式转换;
  • LOAD CSV 的两个前置:锚点索引 + 周期提交;
  • admin import 只吃空库,清洗在文件侧完成;
  • 分批是驱动批量写入的灵魂:每批一事务,批间可重试。

数据进得来、出得去,还差"看得住、救得回"。下一节:监控与备份。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U