Neo4j 之 Cypher 学习
您目前处于:  2024-08-02

CREATE 语句 创建节点关系

节点:用以表示一条数据记录,在Neo4j 中 节点可以有多个属性和多个标签。

关系:就是用来连接两个节点。关系和节点一样可以包含多个属性,关系也称为图论的边(Edge),其 始端末端 都必须是节点,两头不能为空,即关系不能指向空,也不能从空发起。

Neo4j是一种基于图形结构的NoSQL数据库,它采用了Cypher查询语言来查询和操作图形数据。

  • 节点(node) 是图数据库中的一个基本元素,表示一个具体的实体,可以类比成关系数据库中的记录。Cypher 采用一对圆括号 () 来表示节点,如 (n:角色) 表示一个 角色 节点,n 是变量名,供命令执行时用 n 来访问这个节点,在命令执行完毕后就无法使用了。同时单独的 () 表示一个匿名节点,在匹配时表示匹配所有节点。

  • 标签(label) 是同一类节点的组合,但是并不是在同一标签下的节点一定包含相同属性。

  • 关系 是图数据库中节点之间的连接,也表示成节点之间的边,neo4j中关系是双向的。

  • 路径 是图数据库建立之后,任意两个节点之间的连通管理,是关系的组合。

  • 属性 是对节点以及关系的一种说明,可以类比成关系数据库中的字段或者列,这里需要强调的是,在图数据库中关系也是可以设计属性的。

常用命令:

CQL命令 用法
CREATE 创建 创建节点,关系和属性
MATCH 匹配 检索有关节点,关系和属性数据
RETURN 返回 返回查询结果
WHERE 哪里 提供条件过滤检索数据
DELETE 删除 删除节点和关系
REMOVE 移除 删除节点和关系的属性、节点的标签
ORDER BY以…排序 排序检索数据
SET 设置 添加标签,修改属性
AS 起别名 最后为指定的节点或关系起一个别名

下面是Neo4j中语法知识的详细总结和示例:

1 创建节点

在Neo4j中,可以使用CREATE语句来创建节点和关系。CREATE命令语法:

CREATE (
    <node-name>:<label-name>
)

其中,node-name表示我们要创建的节点名称,label-name表示要创建的节点名称。

CREATE (
   <node-name>:<label-name>
   {     
      <Property1-name>:<Property1-Value>
      ........
      <Propertyn-name>:<Propertyn-Value>
   }
)

其中,Property1-name表示属性是键值对,定义将分配给创建节点的属性的名称;Property1-Value表示属性是键值对,定义将分配给创建节点的属性的值。

下面是创建一个节点的示例:创建一个带有标签(TEST)和属性(name:'TEST-NAME', age:1)的节点:

create (n:Person {name:"Emil", from: "Sweden", klout: 99})

create (:Person {name:"test1", from:"Null", klout: 0}),(:Person {name:"xiaoming", age:18}))

这将创建一个标签为TEST,属性为name和age的节点。

  • create,关键字,表示创建

  • ()代表一个节点

  • n表示一个临时变量名称后面如果使用不到该节点,可以不写

  • Person为赋予该节点的标签名

  • {}表示节点的属性,里面填写具体的属性值

2 创建关系

创建关系,必须要指明关系的类型和关系的方向,否则关系无法创建

在两个已存在节点之间创建关系:

match (n:Person {name:"test1"}),(nn:Person{name:"Emil"}) with n,nn create (n)-[:KNOWS]->(nn)

match (n:Person),(nn:Person) where n.name="xiaoming" and nn.name="xiaohong" create (n)-[:KNOWS]->(nn)

match (n1:Person {name: "xiaoming"}),(n2:Person {name: "xiaohong"}),(n3:Person) where n3.name="xiaolan"
create (n1)-[:KNOWS]->(n3),(n2)-[:KNOWS]->(n3),(n3)-[:KNOWS]->(n2)

一个已存在节点和一个新节点之间创建节点的关系:

match (n:Person {name: "test1"}) create (nn:Person {name: "test2"}),(nn)-[:KNOWS {since: 2020}]->(n)

match (n1:Person {name:"test1"}),(n2:Person {name:"test2"}) create (n3:Person {name:"test3"}),(n3)-[:KNOWS {since:2011}]->(n1),(n3)-[:KNOWS {since: 2022}]->(n2)

match (n1:Person),(n2:Person) where n1.name="xiaoming" and n2.name="xiaohong" create (n3:Person {name:"xiaohui", age:17}),(n2)-[:KNOWS]->(n3),(n1)-[:KNOWS]->(n3)

在两个新节点之间创建关系:

create (n1:Person {name:"test1"})-[r:KNOWS {since:2022}]->(n2:Person)

MATCH (ee:Person) WHERE ee.name = "Emil"
CREATE (js:Person { name: "Johan", from: "Sweden", learn: "surfing" }),
(ir:Person { name: "Ian", from: "England", title: "author" }),
(rvb:Person { name: "Rik", from: "Belgium", pet: "Orval" }),
(ally:Person { name: "Allison", from: "California", hobby: "surfing" }),
(ee)-[:KNOWS {since: 2001}]->(js),(ee)-[:KNOWS {rating: 5}]->(ir),
(js)-[:KNOWS]->(ir),(js)-[:KNOWS]->(rvb),
(ir)-[:KNOWS]->(js),(ir)-[:KNOWS]->(ally),
(rvb)-[:KNOWS]->(ally)

创建属性(设置属性,修改属性也是此方式操作):

match (n:Person)-[r:KNOWS]->(nn:Person) where n.name="Emil" and nn.name="Johan" set r.end=2012 return n,nn

创建标签(添加标签):

create (n {name: "Lone"})    // 创建一个节点,没有标签,有一个属性name

match (n {name: "Lone"}) set n:Person return n        // 节点本来没有标签,新增一个Person标签

match (n) where n.name="Lone" set n:Student return labels(n)        // 节点有一个Person的标签,再新增一个Student标签

3 删

删除节点:删除一个没有任何关系的独立节点(此节点没有任何关系存在)

match (n:Person {name: "Lone"}) delete n

删除一个存在关系的节点:当一个节点有关系存在时,只使用delete删除会报错,操作不成功,此时需要使用detach关键字,但这种删除会将此节点涉及的所有关系一并删除

match (n:Person {name: "test2"}) detach delete n

删除关系

match (n:Person)-[r:KNOWS]->(nn:Person) where n.name="test3" and nn.name="test1" delete r

删除属性

match (n:Person) where n.name="xiaoming" remove n.age return n

match (n:Person)-[r:KNOWS]->(nn:Person) where n.name="Emil" and nn.name="Johan" remove r.end return n,r,nn

删除标签

match (n:Person) where n.name="test3" remove n:Person return n

清空数据库:命令删除,此种方式会先读取数据,再删除,所以不适用于数据库数据太大的情况

match (n) detach delete n

4 改

修改属性,节点和关系的属性修改方式一样

match (n:Person) where n.name="xiaoming" set n.name="XiaoMing" return n

match (n:Person)-[r:KNOWS]->(nn:Person) where n.name="Emil" and nn.name="Johan" set r.since=2000 return n,nn

修改节点的标签:无法直接修改,需要先删除要修改的标签,再增加新的标签

match (n) where n.name="test1" remove n:Person set n:Student return n

修改关系类型:无法直接修改,需要先创建新类型的关系,新关系可以复制老关系的属性(属性不变则复制,属性变化则从新设置),最后将老关系删除

match (n:Person)-[r:KNOWS]->(nn:Person) where n.name="Emil" and nn.name="Johan" create (n)-[r2:LIKES]->(nn) set r2=r delete r

5 查

查找节点(包含了id、标签和属性):只涉及节点属性的查找

match (n) return n        // 查找所有节点,有显示上限

match (n:Person) where n.name = "Emil" return n        // 通过节点的属性过滤,返回匹配的节点信息
match (n:Person {name: "Emil"}) return n
// n
// {
//   "identity": 0,
//   "labels": [
//     "Person"
//   ],
//   "properties": {
// "name": "Emil",
// "from": "Sweden",
// "klout": 99
//   }
// }

match (n:Person) where n.name = "Emil" return properties(n)        // 通过节点的属性过滤,只返回匹配节点的属性
//    properties(n)
// {
//   "name": "Emil",
//   "from": "Sweden",
//   "klout": 99
// }

match (n:Person) where n.name = "Emil" return labels(n)        // 通过节点的属性过滤,返回节点的标签
// labels(n)
// ["Person"]

match (n:Person {name:"Emil"}) return id(n)        // 返回节点的id
// id(n)
// 0
  • match,关键字,表示匹配查询

  • n表示一个临时变量名称后面如果使用不到该节点,可以不写

  • Person表示查找的节点的标签名称为“Person”

  • where,关键字,过滤功能

  • n.name = "Emil",过滤条件,表示要查找的节点的属性中的name要为"Emil"

  • return,返回数据

  • properties(n)表示节点n的属性,labels(n)表示节点n的标签

涉及节点关系的查找:查找时指明关系方向

match (n:Person)-[:KNOWS]->(friends) where n.name = "Johan" return n,friends        // 返回的是节点所有数据,只需要属性的话加properties(n)

match (n)-[r:KNOWS|LOVE]-(nn) return n,nn

查找时不指明方向:和上面的命令类似,只是没有指明关系方向

match (n:Person)-[:KNOWS]-(friends) where n.name = "Johan" return n,friends

查询关系(包含了类型和属性)

match (n:Person)-[r:KNOWS]->(friends) where n.name = "Johan" return r

6 复杂查询

起始节点和结束节点之间不直接相连,中间存在其它节点,且路径不唯一

match (n:Person {name:"Emil"})-[r:KNOWS*3]->(nn:Person {name:"Allison"}) return r
// match (n:Person {name:"Emil"})-[r*3]->(nn:Person {name:"Allison"})  return r
// match (n:Person {name:"Emil"})-[r*2..3]->(nn:Person {name:"Allison"})  return r        不定长关系 
// r:KNOWS*3代表 从n到nn要经过三个关系(三条边)
// 返回了一个列表,里面有两条数据,即有两种方案

[
{
  "identity": 7,
  "start": 0,
  "end": 8,
  "type": "KNOWS",
  "properties": {
"since": 2000
  }
}
, 
{
  "identity": 12,
  "start": 8,
  "end": 9,
  "type": "KNOWS",
  "properties": {

  }
}
, 
{
  "identity": 15,
  "start": 9,
  "end": 11,
  "type": "KNOWS",
  "properties": {

  }
}
]
[
{
  "identity": 7,
  "start": 0,
  "end": 8,
  "type": "KNOWS",
  "properties": {
"since": 2000
  }
}
, 
{
  "identity": 13,
  "start": 8,
  "end": 10,
  "type": "KNOWS",
  "properties": {

  }
}
, 
{
  "identity": 16,
  "start": 10,
  "end": 11,
  "type": "KNOWS",
  "properties": {

  }
}
]

7 模糊查询

模糊匹配对象

match (n:Person) where n.name=~".*Em.*" return n        // 使用=~进行模糊匹配查询,正则匹配

match (n) where n.name=~".*Ming.*|.*hong.*" return n
match (n) where n.name=~".*Ming.*" or n.name=~".*hong.*" return n

contains

match (n) where n.name contains "Ming" return n            // 名字中包含Ming的人(节点)

starts with

match (n)-[r]->(nn) where n.name starts with "E" return distinct n
// 查询节点名字是E字母开头的人,并且去重,因为n认识两个人,所以匹配到了两次,不加入关系的话匹配到一次
match (n) where n.name starts with "E" return n

ends with

match (n)-[r]->(nn) where n.name ends with "an" return distinct n

match (n) where n.name ends with "an" return n

引用:

https://www.cnblogs.com/uninterester/p/16975073.html


转载请并标注: “本文转载自 linkedkeeper.com (文/然行)”  ©著作权归作者所有