【知识图谱】Neo4j 导入数据构建知识图谱的三种方法

目录html

Neo4j数据导入5种方式java

一、使用Cypher语言建立node

1.1 建立节点【create】sql

1.2 修改节点的属性mongodb

1.3 建立带属性值的节点docker

1.4 建立节点间的关系shell

1.5 其余操做命令数据库

1.6 cypher查询语言的使用规律windows

二、使用load csv导入数据浏览器

2.1 构建容器(非必须)

2.2 导入节点csv文件

2.3 建立索引并删除重复节点

2.4 导入关系csv文件

三、使用neo4j-admin导入数据

3.1 数据导入前的准备工做

3.2 数据预处理

3.3 数据导入

3.4 查看知识图谱

四、总结


Neo4j数据导入5种方式

neo4j的数据导入方式有不少,总结起来总共分为如下5种:

  1. Cypher CREATE 语句,为每一条数据写一个CREATE
  2. Cypher LOAD CSV 语句,将数据转成CSV格式,经过LOAD CSV读取数据。
  3. 官方提供的Java API —— Batch Inserter
  4. 大牛编写的 Batch Import 工具
  5. 官方提供的 neo4j-import 工具

物种方式的优缺点对比:

一、使用Cypher语言建立

1.1 建立节点【create】

第一种方式:  merge(n:洛杉矶湖人)     # 节点不存在,则建立,存在,则忽略。

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

效果就是,洛杉矶湖人这类的节点,一共被建立了两次,所以,查询的时候,会出现两个Node。虽然上面咱们建立了两个节点,可是这两个节点除了系统给的惟一id外,没有其余属性,下面我就基于这两个节点,分别对它们进行“update”,赋予节点意义。

1.2 修改节点的属性

首先:查询ID等于21798的Node

match(n) where ID(n) = 21798 return n   
#  别忘了查询节点,最后要return n返回节点.

其次:给该Node添加三个属性,分别是label(节点标签名),height(身高),position(场上位置)

neo4j查询节点用:match   == 至关于关系型数据库的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

区别:关系型数据库若是字段不存在的话会报错,而NoSql数据库neo4j,若是属性字段不存在的话,就添加

执行后,效果以下:

1.3 建立带属性值的节点

咱们使用create建立另外一位湖人传奇巨星奥尼尔这个节点,语句以下:

create(n:洛杉矶湖人{label:'奥尼尔',height:216,position:'中锋'}) return n

效果以下:

1.4 建立节点间的关系

构成一条关系最基本的要素是要有两个对象,放在neo4j图库中就是,两个节点,一条边,才能称做是一个完整的关系。建立统一用create命令,而关系的建立,实际上和建立节点差很少,惟一区别就是,关系是有方向的,并且关系用‘[]’表示,而节点用'()'表示。

下面我给目前尚存在的两个节点,科比和奥尼尔建立一条关系,关系的name叫“搭档”,这种关系,不区分方向,所以,无所谓谁是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

解释一下:

一、首先匹配找到节点n和b,也就是科比和奥尼尔表明的节点Node;

二、而后建立节点n到节点b的关系r,r有三个属性,一个是从哪一年开始since,一个是关系描述des,另外一个是合做拿过的冠军数量champion;

三、最后返回n,r,b 完整节点之间的关系结果,table数据以下,总过三列:
 

最终,建立的graph图效果以下:

1.5 其余操做命令

若是要修改关系的属性,和修改节点的属性同样,修改关系的属性也用set,如修改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),掌握如下规律,你就能够快速掌握如何使用Cypher语言。

结合表达式:  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.....   delete n 或者 delete r  或者 delete b 或者 delete n , r , b

 

二、使用load csv导入数据

2.1 构建容器(非必须)

docker环境下安装:这里说明下,默认将容器的/data,/var/lib/neo4j/import目录映射到宿主机。/data存储的是数据,/var/lib/neo4j/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命令行直接导入数据。这样的方式,能够不停用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节点的库里,没有建立index,那么导入关系的时候,将会慢的要死。

# 建立索引以前,咱们插入的节点数据有可能会有重复的状况,咱们须要先清除一下重复数据。
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);

三、使用neo4j-admin导入数据

经过neo4j-admin方式导入的话,须要暂停服务,而且须要清除graph.db,这样才能导入进去数据。并且,只能在初始化数据时,导入一次以后,就不能再次导入了。因此这种方式,能够在初次建库的时候,导入大批量数据,等之后若是还须要导入数据时,能够采用上边的方法。

3.1 数据导入前的准备工做

对于大规模的数据集,使用语句插入和load csv的时候每每很是缓慢,当须要插入大量三元组时,能够考虑使用Neo4j-import的方式。这种方式有许多注意点

# 三元组数据导入前的准备工做
一、传入文件名的时候务必使用绝对路径。
二、在执行指令以前务必保证Neo4j处于关闭状态,若是不肯定能够在Neo4j根目录下运行./bin/neo4j status 查看当前状态。
三、使用neo4j-admin import指令导入以前先将原数据库从neo4j_home/data/databases/graph.db/中移除。
四、写CSV文件的时候务必确保全部的节点的CSV文件的ID fileds的值都惟1、不重复。而且确保全部的边的CSV文件的START_ID 和 END_ID都包含在节点CSV文件中。

3.2 数据预处理

neo4j-import官方要求的数据格式为csv文件,主要就是分红两个文件entity.csv 和relationship.csv。

其中entity.csv中包含了实体的id,实体的name,以及标签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

relationship.csv文件包含了起始节点id,结束节点id,关系的name,以及标签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,适宜人群,适宜人群

须要将导入的数据转换成这样的两个格式的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个节点(由于1000原数据中的节点有重复的),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导入大量数据就成功了。

四、总结

以上介绍了create、load csv、neo4j-admin三种主要的数据导入方式,Batch Inserter和 Batch Import相对用的很少,Batch Inserter是须要在Java中使用,Batch Import能够参考该连接,本文介绍的三种方式基本知足了各类数量级别的数据导入构建知识图谱的要求,总有一款适合你!