知识图谱由于其数据包含实体、属性、关系等,常见的关系型数据库诸如MySQL之类不能很好的体现数据的这些特点,因此知识图谱数据的存储一般是采用图数据库(Graph Databases)。而Neo4j是其中最为常见的图数据库。
使用版本:Neo4j Community Edition 4.2.6(2021年5月5日版本)
cmd里打上(注意先配好环境变量,把bin文件路径加到path里即可)neo4j.bat console,等待片刻,出现
7474一个网址,复制到browser里,即可打开。
来到主界面,单机Graph DBMS的start按钮,等待启动
启动之后按左边第3个按钮,找到Neo4j Browser,点击open启动,来到neo4j的网页交互页面。
首先先删除之前已有的节点和关系,语句为:
match (n) detach delete n
其中,match是匹配操作,而小括号()代表一个节点node,括号里面的n为标识符,是一个泛指,没有指定是哪个具体节点,即泛指所有节点。
创建一个节点,类型可以为Person或Location等等,命令为:
create (n:Person{name:'John'}) return n
其中create是创建操作,n没有具体意义,只代表某个标签。Person是label标签名,代表节点类型;花括号{}代表节点的属性,属性可以为name,age等等。这条语句的含义就是创建一个标签为Person的节点,该节点具有一个name属性,值是John。还可以给该节点定义其他属性,通常一个label包含若干个属性。单击table可以看到:
其中identity是节点的唯一标识,以后用match查询时,where可以通过identity直接锁定某个节点。
接下来我们再创建另外5个Person节点,并分别命名
CREATE (n:Person {name:'Sally'}) RETURN n
CREATE (n:Person {name:'Steve'}) RETURN n
CREATE (n:Person {name:'Mike'}) RETURN n
CREATE (n:Person {name:'Liz'}) RETURN n
CREATE (n:Person {name:'Shawn'}) RETURN n
下面我们创建另外一种节点类型:地区节点Location,其包含两种属性:city和state
CREATE (n:Location {city:'Miami', state:'FL'})
CREATE (n:Location {city:'Boston', state:'MA'})
CREATE (n:Location {city:'Lynn', state:'MA'})
CREATE (n:Location {city:'Portland', state:'ME'})
CREATE (n:Location {city:'San Francisco', state:'CA'})
两种类型的节点都创建好了,下面我们创建它们之间的关系,把它们连起来:
match (a:Person {name:'Liz'}), (b:Person {name:'Mike'}) merge (a)-[r:Friends]->(b)
分两步:
MATCH (a:Person {name:'Shawn'}), (b:Person {name:'Sally'}) MERGE (a)-[:FRIENDS {since:"2001"}]->(b)
可以看到,下方出现了since:2001字样,即我们创建的关系属性
还可以在创建节点的时候就建好关系(即不用分两步先Create再Match和Merge)
CREATE (a:Person {name:'Todd'})-[r:FRIENDS]->(b:Person {name:'Carlos'})
不过这种方式一般不用,正常的流程还是先创建节点,再将某两个节点连接起来。
再添加几个关系,把若干个Person连接起来。注意关系不一定是Friends,也可以是Married等,
MATCH (a:Person {name:'Shawn'}), (b:Person {name:'John'}) MERGE (a)-[:FRIENDS {since:"2012"}]->(b)
MATCH (a:Person {name:'Mike'}), (b:Person {name:'Shawn'}) MERGE (a)-[:FRIENDS {since:"2006"}]->(b)
MATCH (a:Person {name:'Sally'}), (b:Person {name:'Steve'}) MERGE (a)-[:FRIENDS {since:"2006"}]->(b)
MATCH (a:Person {name:'Liz'}), (b:Person {name:'John'}) MERGE (a)-[:MARRIED {since:"1998"}]->(b)
建好之后如下图所示:
然后,不同类型的节点之间也可以建立关系,例如人物Person和地点Location之间
MATCH (a:Person {name:'John'}), (b:Location {city:'Boston'}) MERGE (a)-[:BORN_IN {year:"1978"}]->(b)
MATCH (a:Person {name:'Liz'}), (b:Location {city:'Boston'}) MERGE (a)-[:BORN_IN {year:"1981"}]->(b)
MATCH (a:Person {name:'Mike'}), (b:Location {city:'San Francisco'}) MERGE (a)-[:BORN_IN {year:"1960"}]->(b)
MATCH (a:Person {name:'Shawn'}), (b:Location {city:'Miami'}) MERGE (a)-[:BORN_IN {year:"1960"}]->(b)
MATCH (a:Person {name:'Steve'}), (b:Location {city:'Lynn'}) MERGE (a)-[:BORN_IN {year:"1970"}]->(b)
1.查询所有出生(Born in)在波士顿(Boston)的所有人(Person):
match (a:Person)-[:BORN_IN]->(b:Location{city:'Boston'}) return a,b
解释:先match上两个节点,a和b,a是person类型,b是location类型,并且含有属性city=“boston”,找到了这两个节点后,关系是BORN_IN,返回a和b两个节点。
2.查询所有对外有关系的节点
MATCH (a)-->() RETURN a
注意这里箭头的方向,返回结果不含任何地区节点,因为地区并没有指向其他节点(只是被指向)。
3.查询所有有关系的节点
MATCH (a)--() RETURN a
对比2发现这里就没有箭头了,即不带方向。
4.查询所有对外有关系的节点,以及关系类型
MATCH (a)-[r]->() RETURN a.name, type(r)
注意此处返回两个东西,第一个是节点a的属性name(参照java的写法),第二个是关系r的类型,即Friends或Married或Born_in等。
可以看到返回的a节点都是Person,因为Location没有指向的节点,只是被指向。
5.查询所有有结婚关系的节点
match (n)-[:MARRIED]-() return n
因为不需要返回关系相关的信息(例如关系类型type等),故此处关系的名称不用写了
6.查找某人的朋友的朋友
MATCH (a:Person {name:'Mike'})-[r1:FRIENDS]-()-[r2:FRIENDS]-(friend_of_a_friend) RETURN friend_of_a_friend.name AS fofName
1.用set方法,表示修改操作:
MATCH (a:Person {name:'Liz'}) SET a.age=34
MATCH (a:Person {name:'Shawn'}) SET a.age=32
MATCH (a:Person {name:'John'}) SET a.age=44
MATCH (a:Person {name:'Mike'}) SET a.age=25
解释:先match上某个节点,把它的age属性改为想要的值(若不含age属性则新创建一个age属性)
2.删除节点的属性
用remove方法来删除属性
MATCH (a:Person {name:'Mike'}) SET a.test='test'
MATCH (a:Person {name:'Mike'}) REMOVE a.test
解释:先给名叫Mike的人创建了一个test属性,然后再把该属性删掉
3.删除节点
用Delete方法来删除节点
MATCH (a:Location {city:'Portland'}) DELETE a
4.删除有关系的节点
MATCH (a:Person {name:'Todd'})-[rel]-(b:Person) DELETE a,b,rel
即删除名字属性为Todd的所有有关系的节点和关系