GQL 入门:创建图并完成增删改查¶
本文在悦数图管理控制台中创建一张练习图,演示如何用 GQL 定义图结构、写入数据、查询关系、更新属性和删除数据。练习中会创建两个表示人的点 Alice 和 Bob,以及一条从 Alice 指向 Bob 的“认识”关系。
开始前¶
先以root登录悦数图管理,再在顶部导航栏中单击控制台。使用其他客户端时,见使用 ngql 或内置网页控制台。本文无需加载movie示例数据集。
本文将新建图类型gql_practice_type和图gql_practice,这两个名称应尚未被使用。再次完整练习时,按重新练习更换名称。
按顺序逐个执行代码块:将语句粘贴到查询编辑器,单击运行按钮;成功后,将编辑器中的内容替换为下一条语句。结果表以悦数图管理的表格视图为例,字符串显示在双引号中。
1. 定义图结构¶
图类型定义图中允许有哪些点、边和属性;图保存符合该类型的数据。本次练习使用以下结构:
| 元素 | 类型 | 属性 | 说明 |
|---|---|---|---|
| 点 | Person |
id、name、age |
在图中用id唯一区分Person点 |
| 边 | Knows |
since |
从一个Person指向另一个Person,since表示认识的年份 |
本文使用默认 Schema/default_schema。Schema 类似文件夹,用于组织图类型和图。
切换回默认 Schema
如果此前在控制台中切换过 Schema,先执行以下语句,再继续创建图类型:
SESSION SET SCHEMA /default_schema
执行以下语句,创建图类型gql_practice_type:
CREATE GRAPH TYPE gql_practice_type AS {
NODE Person (LABEL Person {id INT64 PRIMARY KEY, name STRING, age INT32}),
EDGE Knows (Person)-[:Knows {since INT32}]->(Person)
}
语句中各部分的含义:
NODE Person定义点类型,EDGE Knows定义边类型。INT64和INT32是整数类型,STRING是字符串类型。PRIMARY KEY将id指定为主键。同一图中,两个Person点不能使用相同的id。LABEL Person和:Knows分别定义点和边的标签。本例中,类型和标签使用相同名称。
更多解释见图数据基本概念。
使用 ngql 或内置网页控制台
按ngql连接步骤或内置网页控制台连接步骤连接悦数图数据库开发版。只需完成连接,无需加载示例数据;连接后在同一客户端中依次执行本文语句。
在ngql中,多行语句首尾各用一行'''包围。例如,创建图类型时输入:
'''
CREATE GRAPH TYPE gql_practice_type AS {
NODE Person (LABEL Person {id INT64 PRIMARY KEY, name STRING, age INT32}),
EDGE Knows (Person)-[:Knows {since INT32}]->(Person)
}
'''
输入末尾的'''并按 Enter 后提交。本文其余多行语句也使用相同方式。ngql默认表格中的 Alice、Bob 等字符串不带双引号,属性值与本文结果表相同。
在内置网页控制台中,多行语句可直接粘贴到编辑器,并单击运行按钮执行。
2. 创建并选择图¶
基于刚才的图类型创建练习图:
CREATE GRAPH gql_practice TYPED gql_practice_type
将它设置为当前会话的工作图,后续读写语句就会访问这张图:
SESSION SET GRAPH gql_practice
重新连接或为单条语句指定图
重新连接或切换客户端后,需要在新会话中再次执行SESSION SET GRAPH gql_practice。
也可以在单条读写语句的开头用USE指定图,例如:
USE gql_practice
MATCH (p@Person)
RETURN p.name
USE只对所在语句生效,不更改会话工作图。更多信息见 USE。
3. 插入点和边¶
先插入 Alice 和 Bob。以下插入语句各执行一次,每个代码块单独运行:
INSERT (p@Person {id: 1, name: "Alice", age: 30})
INSERT (p@Person {id: 2, name: "Bob", age: 28})
@Person指定点类型,花括号中是属性及其值。p是语句中的变量名,后续语句可以使用其他变量名引用同一个点。
再找到这两个已存在的点,在它们之间插入一条边:
MATCH (a@Person {id: 1}), (b@Person {id: 2})
INSERT (a)-[r@Knows {since: 2024}]->(b)
MATCH按主键找到 Alice 和 Bob,分别绑定到变量a和b。INSERT使用这两个点创建Knows边;箭头表示边从 Alice 指向 Bob。
重复插入数据
请勿重复执行已经成功的插入语句。相同主键的点或相同起点、终点的Knows边已存在时,普通INSERT会报冲突错误。其他冲突处理方式见 INSERT。
4. 查询点和关系¶
查看图中的人¶
MATCH (p@Person)
RETURN p.id AS id, p.name AS name, p.age AS age
ORDER BY id
预期结果:
| id | name | age |
|---|---|---|
| 1 | "Alice" | 30 |
| 2 | "Bob" | 28 |
MATCH (p@Person)匹配所有Person点。RETURN选择结果列,AS为列命名,ORDER BY id按编号排序。
按属性筛选¶
查询年龄大于 28 岁的人,使用WHERE指定筛选条件:
MATCH (p@Person)
WHERE p.age > 28
RETURN p.name AS name, p.age AS age
预期结果:
| name | age |
|---|---|
| "Alice" | 30 |
沿关系查找¶
查询 Alice 认识谁,以及从哪一年开始认识:
MATCH (a@Person {id: 1})-[r@Knows]->(b@Person)
RETURN a.name AS person,
b.name AS friend,
r.since AS known_since
预期结果:
| person | friend | known_since |
|---|---|---|
| "Alice" | "Bob" | 2024 |
圆括号表示点,方括号表示边。变量r引用这条边,可以用r.since读取边的属性。这个模式从 Alice 出发,沿Knows边的方向查找目标点。
5. 更新属性¶
将 Alice 的年龄改为31:
MATCH (p@Person {id: 1})
SET p.age = 31
MATCH定位要修改的点,SET为属性赋新值。更新后重新查询:
MATCH (p@Person {id: 1})
RETURN p.name AS name, p.age AS age
预期结果:
| name | age |
|---|---|
| "Alice" | 31 |
再将 Alice 和 Bob 开始认识的年份改为2023:
MATCH (a@Person {id: 1})-[r@Knows]->(b@Person {id: 2})
SET r.since = 2023
再次运行关系查询时,known_since应为2023。主键属性id不支持通过SET修改。
6. 删除边和点¶
先删除 Alice 到 Bob 的Knows边:
MATCH (a@Person {id: 1})-[r@Knows]->(b@Person {id: 2})
DELETE r
再次运行关系查询,应不再返回这条关系。删除边后,Alice 和 Bob 两个点仍然存在。
再删除 Alice。普通DELETE只能删除没有连接边的点,因此需要先执行上面的删边操作:
MATCH (p@Person {id: 1})
DELETE p
检查剩余点:
MATCH (p@Person)
RETURN p.id AS id, p.name AS name, p.age AS age
ORDER BY id
此时应只返回 Bob:
| id | name | age |
|---|---|---|
| 2 | "Bob" | 28 |
图gql_practice和图类型gql_practice_type仍然保留。
同时删除点及其连接的边
如果 Alice 和这条边仍然存在,可以用以下一条语句替代本节的两个删除步骤。已完成上述删除操作时,无需再执行:
MATCH (p@Person {id: 1})
DETACH DELETE p
DETACH DELETE删除 Alice 及其所有连接的边,并保留 Bob。
重新练习
再次完整练习时,换用尚未使用的图类型和图名称。例如,在本文所有语句中统一替换以下名称,再从第 1 步开始:
| 原名称 | 再次练习时使用的名称 |
|---|---|
gql_practice_type |
gql_practice_type_2 |
gql_practice |
gql_practice_2 |
只需查询已有练习图时,先执行SESSION SET GRAPH gql_practice,再运行查询。数据保留此前修改后的状态;完成本文的删除步骤后,图中只剩 Bob,不会再返回开头的完整结果。