在之前的文章中,介绍了如何搭建neo4j集群,集群的故障切换和节点恢复,还介绍了如何配置驱动实现自动failover。本文聚焦在neo4j的数据上。聊聊如何从外部数据源将数据导入neo4j,如何对neo4j数据库进行备份和恢复。
数据导入
可以有多种方式将数据导入neo4j。大致分为cypher语句导入、apoc.load函数过程导入和离线import导入。
cypher语句导入
这个最简单,就是直接使用cypher语句的create或merge命令来创建neo4j的节点、边和属性。对比来说,create性能较好,但其不会进行存在与否的检查,可能会导致数据库中出现2个相同的节点等情况,造成数据不一致。merge虽性能较差,但功能强大很多。在导入场景,merge一般与on create和on match配合使用,导入语句形如:
MERGE (keanu:Person { name: 'Keanu Reeves' })
ON CREATE SET keanu.created = timestamp()
ON MATCH SET keanu.lastSeen = timestamp()
RETURN keanu.name, keanu.created, keanu.lastSeen
apoc.load函数过程
apoc是neo4j的一个插件(plugin),需要额外安装。可以从github neo4j-apoc-procedures上下载apoc的jar包,放入neo4j对应的plugins目录下,设置如下参数后重启neo4j进程后即可使用。
dbms.security.procedures.unrestricted=apoc.*
apoc.import.file.enabled=true
apoc的功能很强大,其使用文档可通过该链接查看。本文主要关心导入部分。 apoc支持导入json和csv两种格式的数据文件。数据文件内部格式可分为2种,对于csv格式,还分带schema行的(或者成为文件头)和不带schema的。apoc.load均可处理。可参考Neo4j APOC 使用做进一步了解。在此不详说。
离线import
使用neo4j-admin import,输入文件为csv格式。这是性能最好的导数据方式,但其是离线的,也就是neo4j进程关闭状态。不支持增量导数据,即图数据库中已存在的数据会被删除(或被重命名为其他数据库)。所以,import工具一般用于图数据库初始化后,全量导数据。 import工具有较大的灵活性,通过增加配置参数来实现多种不同的导入功能。详细介绍可参考import-tool,下面就其中几点展开说明下。
节点的格式和配置
首先来讨论下节点的设置。--nodes[:Label1:Label2]=,这是节点设置的选项。file可以是单独的schema头,也可以是schema头和数据在一起的文件,还可以将数据文件拆分为多个file。
movieId:ID,title,year:int,:LABEL
tt0133093,"The Matrix",1999,Movie
tt0234215,"The Matrix Reloaded",2003,Movie;Sequel
tt0242653,"The Matrix Revolutions",2003,Movie;Sequel
personId:ID,name,:LABEL
keanu,"Keanu Reeves",Actor
laurence,"Laurence Fishburne",Actor
carrieanne,"Carrie-Anne Moss",Actor
上面是2个节点文件,可以看到schema头和数据在同一个文件中,我们以第一个文件为例来说明。可以将“movieId:ID,title,year:int,:LABEL”这行抽出,单独放在一个新文件中作为头文件,可以将每行记录设置为不同的LABEL,同一行记录可设置多个LABEL。如果文件中的LABEL都是一样的,那么可将LABEL标签移到--nodes选项上来。在schema行可以设置各个属性的类型,比如设置year为int类型。如果没有显式设置,默认的属性为字符串。可以看到属性名为movieId这列被标记为ID列,ID用于在创建边是对节点进行索引。作为ID的字段需要具有唯一性,不过import工具允许文件中的ID列是重复的,可以通过设置--ignore-duplicate-nodes去除ID重复的冗余节点;默认的ID字段是字符串的,可以通过--id-type=来指定ID的类型。
需要注意的是,import工具会在导入数据时对ID列进行排序,这是必须的,因为后续在建立节点跟节点关系时,需要通过ID列进行索引,显然只有有序的ID才能够实现高效索引。这就要求我们在导入时一定要合理选择ID列,选择的标准应该跟数据库唯一索引的标准是类似的。不合适的ID列会极大印象import的效率,建议使用数值列作为ID列。
边的格式和配置
通过--relationships[:RELATIONSHIP_TYPE]=来设置边的类型和边的数据文件,文件格式如下:
:START_ID,role,:END_ID,:TYPE
keanu,"Neo",tt0133093,ACTED_IN
keanu,"Neo",tt0234215,ACTED_IN
keanu,"Neo",tt0242653,ACTED_IN
laurence,"Morpheus",tt0133093,ACTED_IN
laurence,"Morpheus",tt0234215,ACTED_IN
laurence,"Morpheus",tt0242653,ACTED