neo4j 5.19.0安装、apoc csv导入导出 及相关问题处理

前言

突然有需求需要用apoc 导入 低版本的图谱数据,网上资料又比较少,所以就看官网资料并处理了apoc 导入的一些问题。

相关地址

apoc 官方安装网址  

apoc 官方导出csv 教程地址

apoc 官方 导入 csv 地址

docker 安装

执行如下命令启动镜像

docker run -d  --name neo4j  \
    -p 7474:7474 -p 7687:7687 \
    -v /home/neo4j/data:/var/lib/neo4j/data \
	-v /home/neo4j/plugins:/var/lib/neo4j/plugins \
	-v /home/neo4j/logs:/var/lib/neo4j/logs \
    -v /home/neo4j/conf:/var/lib/neo4j/conf \
    -v /home/neo4j/import:/var/lib/neo4j/import \
    -e NEO4J_apoc_export_file_enabled=true \
    -e NEO4J_apoc_import_file_enabled=true \
    -e NEO4J_apoc_import_file_use__neo4j__config=true \
	-e NEO4J_AUTH=neo4j/12345678 \
    neo4j:5.19.0

apoc安装

如果没有数据,可以执行下面的语句插入数据,后面导入导出用

CREATE (TheMatrix:Movie {title:'The Matrix', released:1999, tagline:'Welcome to the Real World'})
CREATE (Keanu:Person {name:'Keanu Reeves', born:1964})
CREATE (Carrie:Person {name:'Carrie-Anne Moss', born:1967})
CREATE (Laurence:Person {name:'Laurence Fishburne', born:1961})
CREATE (Hugo:Person {name:'Hugo Weaving', born:1960})
CREATE (LillyW:Person {name:'Lilly Wachowski', born:1967})
CREATE (LanaW:Person {name:'Lana Wachowski', born:1965})
CREATE (JoelS:Person {name:'Joel Silver', born:1952})
CREATE
(Keanu)-[:ACTED_IN {roles:['Neo']}]->(TheMatrix),
(Carrie)-[:ACTED_IN {roles:['Trinity']}]->(TheMatrix),
(Laurence)-[:ACTED_IN {roles:['Morpheus']}]->(TheMatrix),
(Hugo)-[:ACTED_IN {roles:['Agent Smith']}]->(TheMatrix),
(LillyW)-[:DIRECTED]->(TheMatrix),
(LanaW)-[:DIRECTED]->(TheMatrix),
(JoelS)-[:PRODUCED]->(TheMatrix);

apoc 插件地址 下载 apoc-core-5.19.0 的jar,放到 /home/neo4j/plugins

然后编辑  /home/neo4j/conf/neo4j.conf ,添加如下配置

#没装成功的时候需要自己配置插件目录,成功了就不需要
#server.directories.plugins=/var/lib/neo4j/plugins
#下面两个官方是建议需要什么开放什么,我是直接全开放了
dbms.security.procedures.allowlist=apoc.*
dbms.security.procedures.unrestricted=apoc.*
#网上有出现上下面的配置,但是我不配置也没影响
#server.jvm.additional=Dapoc.export.file.enabled=true
#server.jvm.additional=Dapoc.import.file.enabled=true
server.directories.import=/var/lib/neo4j/import

此处有个问题:由于我一开始配置的 neo4j 是别人装的,我将apoc插件放到挂载的 plugins 下,apoc没装成功,也没有错误,把我整蒙了,后面是在 stackoverflow 看到有人给了 server.directories.plugins 配置,试着配一下才成功的,主要是没装成功也看不到错误,排查起来比较费劲。,需要注意下。自己按上面的步骤应该安装是不需要配置的。

apoc导出

然后执行如下指令导出数据

 CALL apoc.export.csv.all("movies.csv", {}) 

如果出现如下界面,表示插件安装成功,数据导出成功,文件会导出到 /home/neo4j/import

如果出现下面的错误,就是要考虑配置 server.directories.plugins 

There is no procedure with the name `apoc.export.csv.all` registered for this database instance. Please ensure you've spelled the procedure name correctly and that the procedure is properly deployed.

apoc导入

打开导出的csv 文件,数据格式如下图所示

但是我当时用别人配置服务的数据导出的时候,csv内容如下所示,包括别人从3.x的版本导出的数据也是这样的数据,多出了重复的列名_type,_start_,_end

如果像上面一样有重复的标签,就需要自己删除重复的_type,_start_,_end标签,否则就会出现如下错误

Failed to invoke procedure `apoc.import.csv`: Caused by: java.lang.IllegalStateException: Duplicate key _type (attempted merging values apoc.load.Mapping@45da0937 and apoc.load.Mapping@d89fe8

 然后按如下要求修改movies.csv的内容:

1.将 _id 改成 oldId:ID

2.将 _labels 改为 :LABEL

3.将 _start 改为 oldId:START_ID

4.将 _end 改为 oldId:END_ID

5.将 _type 改为 :TYPE

6.将 _labels 那一列下面的值改成 Movie,Person 用逗号分隔多个标签,去掉所有冒号

 我在基于上述需求改的时候,不小心把 :LABEL  敲成 :LABELS ,于是出现了如下的错误,看的我一脸懵逼

Failed to invoke procedure `apoc.import.csv`: Caused by: org.neo4j.internal.kernel.api.exceptions.schema.IllegalTokenNameException: '' is not a valid token name. Token names cannot be empty or contain any null-bytes.

之后如果基于上面的文件进行直接导入,会出现如下的错误,也很莫名其妙

Failed to invoke procedure `apoc.import.csv`: Caused by: java.lang.ClassCastException: class java.lang.String cannot be cast to class java.util.List (java.lang.String and java.util.List are in module java.base of loader 'bootstrap'

这是因为关系和节点都在同一个 csv 里面,需要拆成两个 csv,一个只有关系,一个只有节点,如下面的图片所示。

然后这两个文件都需要放到 /home/neo4j/import 里面

之后执行命令下面的指令(此处 labels type 都不要传值,这两个配置是指定本次导入的节点配置的 label 和关系配置的 type,我们需要用的label type 都在 csv 里,不需要自己指定)

CALL apoc.import.csv(
  [{fileName: 'file:/node.csv', labels: []}],
  [{fileName: 'file:/relationship.csv', type: ''}],
  { arrayDelimiter: ','}
)

如下结果表示成功

数据正常导入,原数据的 id 被作为 oldId 被插入到 neo4j 

csv数据修改问题

1.我这个 demo 是因为数据量少,所以直接人工修改,不是很费劲,但是人工修改的时候需要注意编码问题,有些编辑工具如 excel 修改后再保存,会修改 csv 的编码,此时导入就会出现乱码,需要自己通过如 notepad 等其他工作,把编码改为UTF-8

2.当数据量特别多的时候,手动改就显得又卡,又难操作了,此时可以考虑参考下面的代码,然后基于自己的要求调整。(apoc 好像是使用opencsv 解析的,也可以考虑用opencsv)

<dependency>
    <groupId>org.apache.commons</groupId>
    <artifactId>commons-csv</artifactId>
    <version>1.7</version>
</dependency>
try (Reader reader = Files.newBufferedReader(Paths.get("movies.csv"))) {
    CSVPrinter csvPrinter = null;
    boolean isFirst = true;
    Iterable<CSVRecord> records = CSVFormat.DEFAULT.parse(reader);
    int recordIndex = 0;
    for (CSVRecord record : records) {
        recordIndex++;
        if (isFirst) {
            isFirst = false;
            List<String> heads = Lists.newArrayList();
            int index = 0;
            for (String s : record) {
                index++;
              
                heads.add(s);
            }
            csvPrinter = new CSVPrinter(
                    Files.newBufferedWriter(
                        new File("gen.csv").toPath(),
                        StandardOpenOption.CREATE, StandardOpenOption.WRITE
                    ), 
                    CSVFormat.DEFAULT.withHeader(
                        heads.toArray(
                            new String[heads.size()]
                        )
                    )
            );
            continue;
        }
        List<String> bodys = Lists.newArrayList();
        int index = 0;
        for (String s : record) {
            if (index == 1) {
                s = s.replaceAll(":", ";").replaceFirst(":", "");
            }
            index++;
            bodys.add(s);
        }
        csvPrinter.printRecord(bodys.toArray(new String[bodys.size()]));
        csvPrinter.flush();
    }
}

### Neo4j Desktop 导出 CSV 文件的方法 在 Neo4j Desktop 中导出数据为 CSV 文件可以通过 Cypher 查询语言实现。以下是具体的操作方式: #### 使用 APOC 插件导出数据 Neo4j 提供了一个强大的插件——APOC(Awesome Procedures on Cypher),可以方便地执行复杂的数据操作,包括导出功能。 1. **启用 APOC 扩展包** 如果尚未安装 APOC 插件,则需要先下载并配置该插件[^4]。确保插件已成功加载到 Neo4j 实例中。 2. **编写查询语句导出节点和关系** 可以通过 `apoc.export.csv.query` 或者 `apoc.export.csv.all` 来完成整个数据库或者特定部分的导出工作。以下是一些常见的用法示例: - 导出所有节点和关系至指定路径: ```cypher CALL apoc.export.csv.all("/path/to/export/all_data.csv", {batchSize:1000}) ``` - 导出满足条件的部分数据: ```cypher CALL apoc.export.csv.query( "MATCH (p:Person)-[:KNOWS]->(f) RETURN p.name AS PersonName, f.name AS FriendName", "/path/to/export/person_friends.csv" ) ``` 上述命令中的 `/path/to/export/` 需要替换为你希望保存文件的具体目录位置。注意,在 Windows 系统下可能需要用双反斜杠 (`\\`) 表示路径分隔符,例如:`C:\\Users\\User\\Desktop\\exported_files`. 3. **验证导出结果** 完成导出之后可以在目标文件夹查看生成的 `.csv` 文件,并确认其内容是否符合预期。 #### 不借助第三方工具的手动方法 如果不想依赖于额外的库或插件,也可以手动构造 SQL 类似的 SELECT 语法来提取所需的信息字段,接着利用内置函数将它们转换成逗号分割的形式写入外部存储介质里去。 例如,对于简单的场景可以直接尝试下面这种方式获取单个属性列表作为基础单元格值集合的一部分: ```cypher // 将标签名为 'Movie' 的所有电影名称存放到 movies.csv 当前用户的家目录下的子文件夹 outputs 下面。 WITH collect(DISTINCT m.title) as titles FROM Movie m UNWIND titles as title TO_CSV(title,'outputs/movies.csv'); ``` 不过这种方法灵活性较差,推荐优先考虑采用前面提到过的基于 APOC 解决方案。 --- ### 注意事项 - 在实际应用过程中,请务必保证所使用的 Neo4j 版本支持对应的功能特性以及 API 接口定义版本兼容性等问题。 - 对于大规模图谱结构迁移任务而言,除了单纯依靠纯文本格式化表达外还可以探索更多高效可行的技术手段比如二进制序列化等形式进一步提升效率降低资源消耗成本等综合因素考量后再做决定最为合适。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值