【知识图谱】Neo4j 导入数据构建知识图谱的三种方法
Neo4j数据导入的主要方法包括以下几种:
Cypher语言
- 使用CREATE语句逐个创建节点、关系或修改现有节点属性。
- 通过LOAD CSV将数据转换为CSV格式并导入。
- 使用官方提供的工具如Batch Inserter或Batch Import工具批量导入数据。
- 通过neo4j-import工具对大规模数据进行一次性导入。
CSV文件- 通过cypher-shell直接加载CSV文件并创建节点或关系。
- 创建索引以优化查询性能并删除重复节点以避免性能瓶颈。
Neo4j-admin- 在初次构建知识图谱时使用,默认模式下只能插入一次数据。
- 需要清除原有数据库后才能进行批量插入。
总结来说:
使用Cypher语言灵活高效
CSV文件适合小规模快速迭代
Neo4j-admin适合大规模一次性构建知识图谱
以上三种方法各有优劣,可根据具体需求选择合适的方案进行数据导入操作。
目录
Neo4j数据导入5种方式
1、使用Cypher语言创建
1.1 创建节点【create】
1.2 修改节点的属性
1.3 创建带属性值的节点
1.4 创建节点间的关系
1.5 其他操作命令
1.6 cypher查询语言的使用规律
2、使用load csv导入数据
2.1 构建容器(非必须)
2.2 导入节点csv文件
2.3 创建索引并删除重复节点
2.4 导入关系csv文件
3、使用neo4j-admin导入数据
3.1 数据导入前的准备工作
3.2 数据预处理
3.3 数据导入
3.4 查看知识图谱
4、总结
Neo4j数据导入5种方式
neo4j的数据导入方式有很多,总结起来总共分为以下5种:
- Cypher CREATE 语句可用于为每一条数据单独创建相应的图结构。
- Cypher LOAD CSV 语句允许导入到CSV格式的数据进行批量处理。
- 官方提供了Java API——Batch Inserter——用于高效地执行插入操作。
- 该工具是由经验丰富的开发者开发的高效的批量导入解决方案。
- 官方推荐使用 neo4j-import 工具来进行超快速的大规模数据导入。
物种方式的优缺点对比:

1、使用Cypher语言创建
1.1 创建节点【create】
第一种方式: merge(n:洛杉矶湖人) # 节点不存在,则创建,存在,则忽略。

第二种方式: create(n:洛杉矶湖人) # 不管节点存不存在,创建

效果表现为,在洛杉矶湖人系列中一共生成了两次。这表明,在查询操作中会返回两个Node实例。我们生成了两个节点对象,在这些对象中除了系统提供的唯一标识符外,并不包含任何额外属性。基于这两个节点对象的具体情况,在后续处理中我将分别对它们进行重置属性值的操作。
1.2 修改节点的属性
首先:查询ID等于21798的Node
match(n) where ID(n) = 21798 return n
# 别忘了查询节点,最后要return n返回节点.
下一步:为该Node增添三个属性参数,并包括label: 节点标签名、height: 身高以及position: 场上位置。
在Neo4j中用于查询数据,其查询方式类似于传统的关系型数据库中的SELECT语句, 等同于现代非关系型数据库如MongoDB中的Find操作
neo4j修改节点属性用:set == 相当于关系型数据库的update...set...
match(n) where ID(n) = 21798 set n.label='科比',n.height=198,n.position='得分后卫' return n
类似sql语句: update n set label = ‘科比’,height=198,position='得分后卫' where id = 21798
主要区别在于,在关系型数据库中当字段不存在时会导致错误发生;而在Neo4j这样的NoSql数据库中,在属性字段不存在的情况下则会进行添加。
执行后,效果如下:

1.3 创建带属性值的节点
我们使用create创建另一位湖人传奇巨星奥尼尔这个节点,语句如下:
create(n:洛杉矶湖人{label:'奥尼尔',height:216,position:'中锋'}) return n
效果如下:

1.4 创建节点间的关系
构成关系的基础要素是两个对象,在Neo4j图库中,则需要两个节点和一条边才能算作一个完整的关联。使用create命令来创建这个关联结构时,请注意其本质与节点的创建方式极为相似。然而具体而言,“唯一区别在于”,该关联具有明确的方向性特征,并且通过[]符号表示;而单个节点则以()符号标识。
对于现有的两个节点——科比和奥尼尔——我们将其之间的关系设置为"搭档"。该关系的名称命名为"搭档"。这条关系是双向的,因此无需指定哪一个作为起点(startNode),哪一个作为终点(endNode)。
match(n),(b) where n.label='科比' and b.label='奥尼尔'
create(n)-[r:搭档{since:1996,des:'NBA史上最强OK组合',champion:3}]->(b)
return n,r,b
解释一下:
1、首先匹配找到节点n和b,也就是科比和奥尼尔代表的节点Node;
随后建立节点n与节点b之间的关系r,并将其定义为具有三个关键属性:自起始年份以来的持续时间、描述性质以及累计获得的冠军数目。
3、最后返回n,r,b 完整节点之间的关系结果,table数据如下,总过三列:

最终,创建的graph图效果如下:

1.5 其他操作命令
在处理关系属性时,请采用集合操作的方式进行设置。例如,在处理id为12513的关系时,请将其des字段设置为"小飞侠&大鲨鱼"的具体语句如下:
match(n)-[r]-(b) where ID(r) = 12513 set r.des='小飞侠&大鲨鱼' return n,r,b
为了删除节点间的关系,我们采用命令delete进行操作;该操作与删除节点的操作相同。
match(n)-[r]-(b) where n.label='科比' and b.label='奥尼尔' delete r return r
如果要查询科比和奥尼尔之间的关系,则语句如下:
match(n)-[r]-(b) where n.label='科比' and b.label='奥尼尔' return n,r,b
如果要创建索引,语法:
CREATE INDEX ON :<label_name> (<property_name>)
为节点标签洛杉矶湖人基于属性label创建索引,语句如下:
create index on:洛杉矶湖人(label)
删除索引:
DROP INDEX ON :<label_name> (<property_name>)
drop index on:洛杉矶湖人(label)
1.6 cypher查询语言的使用规律
实际上,使用Cypher语言进行查询相对简单。无论需要查询的内容是什么,总是围绕着节点、关系以及节点之间的相互关联展开。其基本形式通常表示为:(n)-[r]-(b)
结合表达式: match(n)-[r] -(b)
如果查询节点n 就 return n
如果查询关系r 就 return r
如果查询节点b 就 return b
如果查询节点n和b之间的关系r 就 return n,r,b
如果查询带条件 就 where n.x = x,r.xx = xx,b.xxx = xxx
如果修改属性 就 where..... set ....
如果删除属性 就 where..... remove .....
在删除节点或关系时,请使用WHERE子句指定具体要进行操作的对象:例如可以选择性地进行操作:仅删除n节点、仅删除r关系或仅删除b表。
2、使用load csv导入数据
2.1 构建容器(非必须)
在Docker环境下进行安装时,请详细解释一下,默认情况下会将容器的数据文件(如/data)以及Neo4j导入文件夹(如/var/lib/neo4j/import)映射到宿主机。其中,/data存储的是数据文件本身;而(import)则用于存储你希望导入到数据库中的数据集。
docker run \
--publish=7474:7474 --publish=7687:7687 \
--volume=/data/neo4j/data:/data \
--volume=/data/neo4j/import:/var/lib/neo4j/import \
--env=NEO4J_dbms_memory_pagecache_size=2G \
--env=NEO4J_dbms_memory_heap_max__size=8G \
--name=neo4j \
-d neo4j
在导入大规模数据时可供选择的方式有很多种,并且每个方法都有其独特的挑战。这里指向官网文档。
2.2 导入节点csv文件
利用Cypher shell CLI(Cypher shell Command Line Interface)进行数据集的便捷导入。此方法可使Neo4j服务持续运行并方便地将数据导入至数据库中。
#load node csv
USING PERIODIC COMMIT 1000
LOAD CSV WITH HEADERS FROM "file:/nodes.csv" AS csvLine
CREATE (c:Contact { mobile:csvLine.mobile, name:csvLine.name, updateTime:csvLine.updateTime, createTime:csvLine.createTime });
USING PERIODIC COMMIT 1000,是满足1000条之后,提交一个事务,这样能够提高效率。
2.3 创建索引并删除重复节点
在导入节点后,默认情况下系统会引入关联表。需要注意的是,在node库中如果没有为表建立索引的情况下,默认引入关联表可能会导致查询速度大幅下降
# 创建索引之前,我们插入的节点数据有可能会有重复的情况,我们需要先清除一下重复数据。
MATCH (n:Contact)
WITH n.mobile AS mobile, collect(n) AS nodes
WHERE size(nodes) > 1
FOREACH (n in tail(nodes) | DETACH DELETE n);
#创建索引
CREATE CONSTRAINT ON (c:Contact) ASSERT c.mobile IS UNIQUE;
CREATE INDEX ON :Contact(mobile);
2.4 导入关系csv文件
USING PERIODIC COMMIT 1000
LOAD CSV WITH HEADERS FROM "file:/rels.csv" AS csvLine
MATCH (c:Contact {mobile:csvLine.mobile1}),(c1:Contact {mobile:csvLine.mobile2})
CREATE (c)-[:hasContact]->(c1);
3、使用neo4j-admin导入数据
使用neo4j-admin命令进行导入操作时,请确保先暂停服务并删除graph.db文件。需要注意的是,在初始化阶段仅能执行一次该操作。这使得我们可以高效地在初次构建数据库时一次性导入大量数据。后续若需进行更多数据的导入,则可以采用上述方法。
3.1 数据导入前的准备工作
对于大规模的数据集而言,在进行语句插入或调用load csv时通常会遇到效率问题。尤其是当需要批量插入大量三元组时,则可能影响整体性能表现。该方法涉及多个注意事项:
# 三元组数据导入前的准备工作
1、传入文件名的时候务必使用绝对路径。
2、在执行指令之前务必保证Neo4j处于关闭状态,如果不确定可以在Neo4j根目录下运行./bin/neo4j status 查看当前状态。
3、使用neo4j-admin import指令导入之前先将原数据库从neo4j_home/data/databases/graph.db/中移除。
4、写CSV文件的时候务必确保所有的节点的CSV文件的ID fileds的值都唯一、不重复。并且确保所有的边的CSV文件的START_ID 和 END_ID都包含在节点CSV文件中。
3.2 数据预处理
neo4j-import系统明确规定了数据格式应当采用CSV文件类型,并明确指出将实体信息与关系信息分别存储于entity.csv和relationship.csv两个独立的文件中。
在entity.csv文件中存储了实体的信息,包括每个实体的ID,名称以及对应的标签LABEL
entity:ID,name,:LABEL
e0,GDP,my_entity
e1,PHP,my_entity
e2,李冲,my_entity
e3,perimenopausal syndrome,my_entity
e4,雁荡山景区分散,东起羊角洞,西至锯板岭;南起筋竹溪,北至六坪山。,my_entity
e5,词条(拼音:cí tiáo)也叫词目,是辞书学用语,指收列的词语及其释文。,my_entity
e6,芦苇茂密,结草为荡,my_entity
e7,面粉,水,酵母,苏打,my_entity
e8,先注册先得的原则,my_entity
e9,解压缩软件,my_entity
e10,华硕电脑股份有限公司,my_entity
relation.csv文档包含起始节点id、结束节点ID、关系名称以及标签LABEL的具体格式如下:
:START_ID,:END_ID,name,:TYPE
e48,e799,属性,属性
e191,e479,描述,描述
e641,e5,描述,描述
e641,e182,标签,标签
e237,e575,描述,描述
e237,e237,中文名,中文名
e237,e533,是否含防腐剂,是否含防腐剂
e237,e264,主要食用功效,主要食用功效
e237,e405,适宜人群,适宜人群
为了实现数据导入到Neo4j系统中并确保兼容性需求得到满足,请按照特定要求将导入的数据按照特定要求进行处理后生成两种格式的CSV文件,并确保这些文件能够成功地与Neo4j系统进行数据对接和集成。
3.3 数据导入
csv数据文件准备好后,可以通过执行以下脚本来实现数据导入:
#导入命令
# 停止neo4j服务
neo4j stop
# 如果是Linux可以进入到databases目录下删除数据库,windows直接删除即可
cd /usr/local/Cellar/neo4j/3.5.0/libexec/data/databases
rm -rf graph.db
# 执行数据导入命令neo4j-admin
neo4j-admin import \
--database=graph.db
--nodes:phone="../phone_header.csv,phones.csv \
--ignore-duplicate-nodes=true \
--ignore-missing-nodes=true \
--relationships:call="../call_header.csv,call.csv"
# 重启neo4j服务
neo4j start
出现类似于如下结果,表示导入成功:


结果表明成功引入了841个节点(由于在原始数据中的节点存在重复情况),同时包含1002条关系(实际记录总数为1002),共计存储了1682个属性值。
3.4 查看知识图谱
查看数据结果:当导出完成后,在Neo4j浏览器中即可看到导出的数据内容。访问地址:http://localhost:7474/browser/
知识图谱生成后,重启Neo4j服务:
neo4j start
查看整个知识图谱,使用查询命令:
match(n) return n

查询实体节点为Google的所有对应的关系:
match(n:my_entity)-[r]->(b) where n.name='Google' return n,r,b

至此,neo4j-import导入大量数据就成功了。
4、总结
本文概述了三种主要的数据导入方法:create、load csv以及neo4j-admin。其中一种工具——Batch Inserter——必须在Java环境中进行操作;另一种工具——Batch Import——则相对较少被采用。对于需要大量数据导入构建知识图谱的场景来说,在实际应用中较少使用这两种工具。然而,在这篇文章中介绍的这三种方法能够有效地应对不同规模的知识图谱构建的需求;无论你的需求是什么,在这三者之中总有一款工具能够满足你的要求。
