将Neo4j数据导入到GDB

本文涉及的产品
云原生数据库 PolarDB MySQL 版,Serverless 5000PCU 100GB
云数据库 Redis 版,社区版 2GB
推荐场景:
搭建游戏排行榜
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
简介: 本文通过具体示例,介绍如何将现有的Neo4j数据导入到GDB中。

本文使用具体示例介绍导入Neo4j数据到GDB流程。
在进行操作前需要您已经准备好以下资源。

  1. Neo4j Server,保存有待导出数据,能正常提供读写服务。
  2. Cypher Shell,连接到Neo4j Server,控制台命令交互,导出数据到文件。
  3. 阿里云GDB,数据导入的目的端。
  4. 阿里云OSS,用于临时存放Neo4j导出的中间文件,提供给GDB导入使用。
  5. 中间文件格式转换工具 graphml2csv.py,转换graphML格式文件到GDB支持的CSV格式。
  6. 阿里云GDB导入API小工具 GdbLoader.py,也可以直接使用curl命令交互。

1. 写入测试数据到Neo4j

如果待导出的数据已经保存在Neo4j,可以跳过此步骤,本文演示可操作的完整流程。

Cypher-Shell执行以下语句,写入测试数据(TinkerPop modern)。

# 写入点数据
create (:person {id:"1", name:"marko", age:29});
create (:person {id:"2", name:"vadas", age:27});
create (:person {id:"3", name:"lop", lang:"java"});
create (:person {id:"4", name:"josh", age:32});
create (:person {id:"5", name:"ripple", lang:"java"});
create (:person {id:"6", name:"peter", age:35});

# 写入边数据
start n=node(*), m=node(*) where n.id="6" and m.id="3" create (n)-[:created {id:"12", weight:0.2}]->(m);
start n=node(*), m=node(*) where n.id="4" and m.id="3" create (n)-[:created {id:"11", weight:0.4}]->(m);
start n=node(*), m=node(*) where n.id="4" and m.id="5" create (n)-[:created {id:"10", weight:1.0}]->(m);
start n=node(*), m=node(*) where n.id="1" and m.id="3" create (n)-[:created {id:"9", weight:0.4}]->(m);
start n=node(*), m=node(*) where n.id="1" and m.id="4" create (n)-[:knowns {id:"8", weight:1.0}]->(m);
start n=node(*), m=node(*) where n.id="1" and m.id="2" create (n)-[:knowns {id:"7", weight:0.5}]->(m);

2. 导出Neo4j数据到文件

以下使用Neo4j apoc功能导出数据到文件,文件格式是graphml。注意导出命令的参数。


neo4j> call apoc.export.graphml.all("result.ml",{readlabels:true, useTypes:true});
+-----------------------------------------------------------------------------------------------------------------------------------------+
| file        | source                        | format    | nodes | relationships | properties | time | rows | batchSize | batches | done |
+-----------------------------------------------------------------------------------------------------------------------------------------+
| "result.ml" | "database: nodes(6), rels(6)" | "graphml" | 6     | 6             | 30         | 54   | 0    | -1        | 0       | TRUE |
+-----------------------------------------------------------------------------------------------------------------------------------------+

1 row available after 261 ms, consumed after another 12 ms

由于我们示例的测试数据比较小,以下给出导出文件的完整内容,方便核对。


<?xml version="1.0" encoding="UTF-8"?>
<graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd">
<key id="name" for="node" attr.name="name" attr.type="string"/>
<key id="id" for="node" attr.name="id" attr.type="string"/>
<key id="lang" for="node" attr.name="lang" attr.type="string"/>
<key id="age" for="node" attr.name="age" attr.type="long"/>
<key id="weight" for="edge" attr.name="weight" attr.type="double"/>
<key id="id" for="edge" attr.name="id" attr.type="string"/>
<graph id="G" edgedefault="directed">
<node id="n0" labels=":person"><data key="labels">:person</data><data key="id">1</data><data key="name">marko</data><data key="age">29</data></node>
<node id="n1" labels=":person"><data key="labels">:person</data><data key="id">4</data><data key="name">josh</data><data key="age">32</data></node>
<node id="n2" labels=":person"><data key="labels">:person</data><data key="id">5</data><data key="name">ripple</data><data key="lang">java</data></node>
<node id="n3" labels=":person"><data key="labels">:person</data><data key="id">6</data><data key="name">peter</data><data key="age">35</data></node>
<node id="n20" labels=":person"><data key="labels">:person</data><data key="id">2</data><data key="name">vadas</data><data key="age">27</data></node>
<node id="n21" labels=":person"><data key="labels">:person</data><data key="id">3</data><data key="name">lop</data><data key="lang">java</data></node>
<edge id="e0" source="n3" target="n21" label="created"><data key="label">created</data><data key="id">12</data><data key="weight">0.2</data></edge>
<edge id="e20" source="n1" target="n21" label="created"><data key="label">created</data><data key="id">11</data><data key="weight">0.4</data></edge>
<edge id="e21" source="n1" target="n2" label="created"><data key="label">created</data><data key="id">10</data><data key="weight">1</data></edge>
<edge id="e22" source="n0" target="n21" label="created"><data key="label">created</data><data key="id">9</data><data key="weight">0.4</data></edge>
<edge id="e23" source="n0" target="n1" label="knowns"><data key="label">knowns</data><data key="id">8</data><data key="weight">1</data></edge>
<edge id="e40" source="n0" target="n20" label="knowns"><data key="label">knowns</data><data key="id">7</data><data key="weight">0.5</data></edge>
</graph>
</graphml>

3. 转换导出文件格式

阿里云GDB目前不支持导入graphml格式文件数据,可以使用下面工具转换graphml格式到GDB支持的Gremlin(CSV)格式。

python graphml2csv.py -i result.ml
infile = result.ml
Processing result.ml
Wrote 6 nodes and 24 attributes to result-nodes.csv.
Wrote 6 edges and 18 attributes to result-edges.csv.

转换成功后有以下点和边数据文件,可以看到点边都有一个id的属性字段。

# CSV点数据文件
 $ cat result-nodes.csv
~id,~label,name:string,id:string,lang:string,age:long
0,person,marko,1,,29
1,person,josh,4,,32
2,person,ripple,5,java,
3,person,peter,6,,35
20,person,vadas,2,,27
21,person,lop,3,java,

# CSV边数据文件
 $ cat result-edges.csv
~id,~from,~to,~label,weight:double,id:string
0,3,21,created,0.2,12
20,1,21,created,0.4,11
21,1,2,created,1,10
22,0,21,created,0.4,9
23,0,1,knowns,1,8
40,0,20,knowns,0.5,7

转换常见问题

  1. GDB不支持多label。如果数据中包含多label的点,转换脚本去掉前缀冒号(:),剩下字段当单label值输出。例如两个标签workerdoctor的点,转换后标签是worker:doctor
  2. Neo4j默认隐藏点和边的ID字段,内部使用数值表示。导出graphml格式数据中包含有内部ID字段。由于格式规范要求,点ID会添加字符'n',边ID会添加字符'e',导出脚本转换时去掉了前缀。
  3. graphml格式会在开头定义数据schema,但可能不完整。转换时出现KeyError(xxx)的错误可能就是数据内容不在schema定义的范围内。可参照在文件开头添加该字段的定义。注意点和边是分开定义的。

4. 导入数据文件到GDB

上述转换后得到点和边两个csv数据文件,我们使用GDB导入工具发送导入命令完成数据导入。当然您也可以参照阿里云GDB导入文档使用CURL操作导入。

上传转换后的点、边CSV文件到OSS bucket。注意检查bucket的地域和GDB实例是否相同,如果不一致,可以申请新的相同地域bucket。以下使用OSS命令行工具ossutil上传数据到OSS,请替换您的bucket名称。


#点文件
./ossutil cp result-nodes.csv oss://${mybucket}/neo4j-data/result-nodes.csv

#边文件
./ossutil cp result-edges.csv oss://${mybucket}/neo4j-data/result-edges.csv

使用导入工具依次添加导入点任务和导入边任务,注意等导入点完成后再添加导入边任务,可以使用添加任务时返回的任务ID查询任务详情,检查是否完成。

以下命令需要使用到您的GDB实例参数,可以参照导入文档查找参数值


# 添加导入点任务
python GdbLoader.py --host ${mygdb-endpoint}:8182 --username ${username} --password ${password} --todo add_task --source oss://{mybucket}/neo4j-data/result-nodes.csv --arn acs:ram::${my-uid}:role/${role-name}

# 添加导入边任务
python GdbLoader.py --host ${mygdb-endpoint}:8182 --username ${username} --password ${password} --todo add_task --source oss://${mybucket}/neo4j-data/result-edges.csv --arn acs:ram::${my-uid}:role/${role-name}

# 查询任务详情
python GdbLoader.py --host ${mygdb-endpoint}:8182 --username ${username} --password ${password} --todo get_task --loaderId 552617AF-4F1E-4CD8-9533-A2EC154688DC

5. 验证导入数据

导入完成后,我们就能使用各种SDK接入GDB访问数据,简单起见,下面使用CURL读取一个边数据验证。其他语言的接入验证可以参照GDB各环境的接入文档。

curl -u ${username}:${password} -X POST -d '{"gremlin":"g.E(\"21\").valueMap(true)"}' ${mygdb-endpoint}:8182 | python -m json.tool
相关实践学习
阿里云图数据库GDB入门与应用
图数据库(Graph Database,简称GDB)是一种支持Property Graph图模型、用于处理高度连接数据查询与存储的实时、可靠的在线数据库服务。它支持Apache TinkerPop Gremlin查询语言,可以帮您快速构建基于高度连接的数据集的应用程序。GDB非常适合社交网络、欺诈检测、推荐引擎、实时图谱、网络/IT运营这类高度互连数据集的场景。 GDB由阿里云自主研发,具备如下优势: 标准图查询语言:支持属性图,高度兼容Gremlin图查询语言。 高度优化的自研引擎:高度优化的自研图计算层和存储层,云盘多副本保障数据超高可靠,支持ACID事务。 服务高可用:支持高可用实例,节点故障迅速转移,保障业务连续性。 易运维:提供备份恢复、自动升级、监控告警、故障切换等丰富的运维功能,大幅降低运维成本。 产品主页:https://www.aliyun.com/product/gdb
目录
相关文章
|
4月前
|
存储 SQL NoSQL
案例实践:某券商从 Neo4j 迁移至悦数图数据库
许多国内企业在早期使用 Neo4j 作为图相关业务场景的探索基础设施。然而,随着业务发展和环境变化,原有的图数据库已经逐渐无法满足不断发展的特定业务场景需求。如何将 Neo4j 迁移到一款兼具良好扩展性、性能、专业服务能力的图产品,已成为业界普遍关心的问题。本文将为您呈现华东某大型券商从 Neo4j 迁移至悦数图数据库的选型、迁移和提升能力的完整历程,供广大企业参考。
案例实践:某券商从 Neo4j 迁移至悦数图数据库
|
9月前
|
存储 数据采集 自然语言处理
手把手教学小型金融知识图谱构建:量化分析、图数据库neo4j、图算法、关系预测、命名实体识别、Cypher Cheetsheet详细教学等
手把手教学小型金融知识图谱构建:量化分析、图数据库neo4j、图算法、关系预测、命名实体识别、Cypher Cheetsheet详细教学等
手把手教学小型金融知识图谱构建:量化分析、图数据库neo4j、图算法、关系预测、命名实体识别、Cypher Cheetsheet详细教学等
|
11月前
|
存储 SQL NoSQL
一种新型的NoSQL数据库,图数据库------Neo4J
一种新型的NoSQL数据库,图数据库------Neo4J
|
存储 SQL NoSQL
知识图谱与数据库技术:RDF三元组库和Neo4j图数据库
知识图谱与数据库技术:RDF三元组库和Neo4j图数据库
890 0
|
人工智能 NoSQL Cloud Native
【云原生专题】基于Docker+Neo4j图数据库搭建企业级分布式应用拓扑图
【云原生专题】基于Docker+Neo4j图数据库搭建企业级分布式应用拓扑图
【云原生专题】基于Docker+Neo4j图数据库搭建企业级分布式应用拓扑图
|
NoSQL Python
Python编程:py2neo操作neo4j图数据库
Python编程:py2neo操作neo4j图数据库
270 0
|
NoSQL 数据库 数据安全/隐私保护
Neo4j图数据库的安装与基本增删改查
Neo4j图数据库的安装与基本增删改查
217 0
Neo4j图数据库的安装与基本增删改查
|
存储 缓存 NoSQL
Knowledge Graph |(1)图数据库Neo4j简介与入门
Knowledge Graph |(1)图数据库Neo4j简介与入门
400 0
Knowledge Graph |(1)图数据库Neo4j简介与入门
|
SQL JSON 固态存储
图数据库neo4j数据导入、备份和恢复
在之前的文章中,介绍了如何搭建neo4j集群,集群的故障切换和节点恢复,还介绍了如何配置驱动实现自动failover。本文聚焦在neo4j的数据上。聊聊如何从外部数据源将数据导入neo4j,如何对neo4j数据库进行备份和恢复。 数据导入 可以有多种方式将数据导入neo4j。大致分为cypher语句导入、apoc.load函数过程导入和离线import导入。 cypher语句导入 这个最简单,就是直接使用cypher语句的create或merge命令来创建neo4j的节点、边和属性。对比来说,create性能较好,但其不会进行存在与否的检查,可能会导致数据库中出现2个相同的节点等情况,
1235 0