neo4j图数据库,如何使用create语句创建节点和关系数据?
发布于 作者:苏南大叔 来源:程序如此灵动~已有的neo4j
图数据库的相关文章里,苏南大叔大体上就是一直不停的建库删库进行数据尝试。除了通过csv
文件直接导入数据之外,neo4j
也有自己的查询语言cypher
,可以直接插入数据。对比大家已经熟知的sql
,业内称cypher
为cql
语言。从本文开始,苏南大叔开始涉及neo4j
的专有cypher
查询语言的介绍。
大家好,这里是苏南大叔的“程序如此灵动”博客,这里介绍苏南大叔和计算机代码的故事。本文讲述如何使用普通的语句,来插入一个节点或一条关系。本文测试环境:neo4j@4.4.5
,win10
。龙套主角还是neo4j
官方自带的movie
例子。
因为苏南大叔使用的是neo4j
的社区版,只能用一个默认的图neo4j
。这里就省略了create database neo4j
和use neo4j
的步骤了。
带属性的节点和关系
首先,要说明的是neo4j
数据库里面的数据是什么样的概念。一个图就是由不同的节点,以及这些不同节点之间的关系所组成的。另外,需要明确的是:
(NODE1) - [:RELATION] -> (NODE2)
- 实体有标签,实体可以用一个
string
表示,但是它可以有属性,可以是个object
。 - 关系有类型,关系可以用一个
string
表示,但是它可以有属性,可以是个object
。
这里,还是举个例子来说明:
(苏南大叔) - [:毕业于] -> (北京大学)
实际上,上述语句可以扩充思路成这样:
实体或关系 | 扩充了属性和标签后 |
---|---|
(苏南大叔) | (苏南大叔:Person{name:"sunan",website:"newsn.net'}) |
[:毕业于] | [:毕业于{year:"2022",degree="博士"}] |
(北京大学) | (北京大学:University{titles:['985','211','双一流']}) |
(苏南大叔:Person{name:"sunan",website:"newsn.net'}) - [:毕业于{year:"2022",degree="博士"}] -> (北京大学:University{titles:['985','211','双一流']})
本文中出现了2个冒号的用法,在节点(node:Lable)
中是用于修饰标签的,标签可有可无。在关系[:type]
中是用于描述类型的,类型还是必须存在的。
使用方法 | 说明 |
---|---|
(node) | 没有标签的节点 |
(node:Lable) | 有一个标签的节点 |
(node:Lable1:Label2) | 有两个标签的节点 |
[:type] | 类型为type的关系 |
cypher语句插入节点
cypher语句插入节点的基本格式是:
CREATE (n:Label {prop:'value'})
其中n
部分仅仅是个临时变量,是可以随便写甚至不写,写了也不记录在数据库里面。也就是说:使用者最关心的部分居然是数据库最不关心的部分。是不是有点讽刺...
例如:
建立电影《黑客帝国》(变量是TheMatrix
,标签是Movie
)节点:
CREATE (TheMatrix:Movie {title:'The Matrix', released:1999, tagline:'Welcome to the Real World'})
建立演员"Keanu Reeves"(变量是Keanu
,标签是Person
)的节点:
CREATE (Keanu:Person {name:'Keanu Reeves', born:1964})
TheMatrix
和Keanu
都是那个不入数据库的变量。
这个标签就类似原来的table
的作用,节点里面的属性就是原来的字段名。
说明:
节点可以不指定标签,或者指定多个标签。比如:
CREATE (sunan:Person:Student {name:'sunan',www:'newsn.net'})
CREATE (sunan2 {name:'sunan2',www:'newsn.net'})
或者只有一个标签,甚至只有属性。
CREATE (:Person {name:'sunan3',www:'newsn.net'})
CREATE ({name:'sunan4',www:'newsn.net'})
更有甚者,下面的两个例子也是可以成立的。从效果上看,两者是等价的,都是建立了一个啥都没有的节点。
CREATE (sunan5)
CREATE ()
cypher语句建立关系
cypher语句插入关系的基本格式是:
CREATE (node1)-[:type {prop: 'value'}]->(node2)
对于已有的两个节点,可以使用先match
后create
的方式,例如:
match (sunan:Person{name:'sunan'}),(sunan2:Person{name:'sunan2'})
create (sunan)-[r:similar]->(sunan2) return r;
单独执行的create
语句,没有上下文指出node1
和node2
的话,就会自动创建对应空结点。这样的话是不符合大家的初衷的。这里非常容易忽略误解!必须配合上下文!
这里把Keanu
节点和TheMatrix
节点建立类型为ACTED_IN
的关系,这个关系的属性是:roles
为Neo
。
CREATE (Keanu)-[:ACTED_IN {roles:['Neo']}]->(TheMatrix)
对于这条关系来说,左边和右边都是节点,括号里面是变量,节点的类型是:ACTED_IN
,属性可以不填的,但是类型是必填的。否则可能会遇到如下错误信息:
Exactly one relationship type must be specified for CREATE. Did you forget to prefix your relationship type with a ':'? (line 1, column 10 (offset: 9))
"CREATE ()-[]->()"
关系左右节点变量如果在上下文中不存在的话,会建立两个空节点。也就是说,在neo4j browser
的不同输入执行框里面,不存在上下文关系。这就引入下一个“语句执行的时机”的话题。
可能错误的使用方式
这个cql
和sql
语句一个非常重大的区别开始显示了。sql
一条一条的执行没有问题,一般不会出错。而这个cql
在browser
里面一条条的执行的话,可能就有问题了。主要的问题是变量n
,出了上下文就失效。
如果在browser
里面分开执行上述movie
例子的语句的话,会得到这个错误的结果:
CREATE (TheMatrix:Movie {title:'The Matrix', released:1999, tagline:'Welcome to the Real World'})
CREATE (Keanu:Person {name:'Keanu Reeves', born:1964})
CREATE (Keanu)-[:ACTED_IN {roles:['Neo']}]->(TheMatrix)
两个节点变成了四个节点,关系被绑定到了两个错误的空节点上。
如果三条语句在一起执行的话,则是正确的结果:
CREATE (TheMatrix:Movie {title:'The Matrix', released:1999, tagline:'Welcome to the Real World'})
CREATE (Keanu:Person {name:'Keanu Reeves', born:1964})
CREATE (Keanu)-[:ACTED_IN {roles:['Neo']}]->(TheMatrix)
上述三句并不一致的语句,还可以合并输入,也会得到正确的结果:
CREATE (TheMatrix:Movie {title:'The Matrix', released:1999, tagline:'Welcome to the Real World'}),
(Keanu:Person {name:'Keanu Reeves', born:1964}),
(Keanu)-[:ACTED_IN {roles:['Neo']}]->(TheMatrix)
特殊的使用方式
一个节点多个类型
CREATE (DiyMovie:Movie:Movie2 {title:'The Matrix2', released:2022})
可以设置多个标签,属性是绑定在节点上的,并不是标签上,写多个:
就可以。
两个节点多条关系
两个节点之间有多个关系的话,就执行多次create
里面就好了。
CREATE (Keanu)-[:ACTED_IN {roles:['Neo']}]->(TheMatrix),
(Keanu)-[:ACTED_IN2 {roles:['Neo']}]->(TheMatrix)
使用汉字并建立双标签
CREATE (十二度:商品:啤酒 {名称:'唐山12度啤酒',编码:'6914340999976',价格:36,规格:'500ml*12',有效期:'9个月'});
注意:数字开头不能用做变量名。也就是说"十二度"的字样不能写成"12度",会报错。
参考文献
- https://neo4j.com/docs/cypher-manual/current/query-tuning/basic-example/#_movies
- https://newsn.net/say/neo4j-win.html
综述
本文里主要讲述的就是非常非常基础的插入数据的动作,一般来说,插入单独的节点是没有意义的,插入单独的关系也是不能实现的。只有两个节点加上一条关系,才是条完整的记录。所以,完成一个具有完整意义的数据插入,实际上至少执行三条语句才能实现:插入两个节点,两个节点上建立个关系。
更多cypher
的语句介绍,请点击苏南大叔的博客:
本博客不欢迎:各种镜像采集行为。请尊重原创文章内容,转载请保留作者链接。