1. 使用说明
图空间和 Schema
一个 NebulaGraph 实例由一个或多个图空间组成。每个图空间都是物理隔离的,用户可以在同一个实例中使用不同的图空间存储不同的数据集。
为了在图空间中插入数据,需要为图数据库定义一个 Schema。 NebulaGraph 的 Schema 是由如下几部分组成。
组成部分 | 说明 |
---|---|
点(Vertex) | 表示现实世界中的实体。一个点可以有 0 到多个标签。 |
标签(Tag) | 点的类型,定义了一组描述点类型的属性。 |
边(Edge) | 表示两个点之间有方向的关系。 |
边类型(Edge type) | 边的类型,定义了一组描述边的类型的属性。 |
异步实现创建和修改
在 NebulaGraph 中,下列创建和修改操作是异步实现的。要在下一个心跳周期之后才能生效,否则访问会报错。为确保数据同步,后续操作能顺利进行,请等待 2 个心跳周期(20 秒)。
- CREATE
- SPACE
- CREATE TAG
- CREATE EDGE
- ALTER TAG
- ALTER EDGE
- CREATE TAG INDEX
- CREATE EDGE INDEX
2. 创建和选择图空间
# 创建名为basketballplayer的图空间
CREATE SPACE basketballplayer(partition_num=15, replica_factor=1, vid_type=fixed_string(30));
# 检查分片的分布情况,确保平衡分布
SHOW HOSTS;
# 选择图空间
USE basketballplayer;
# 查看创建的图空间
SHOW SPACES;
3. 创建 Tag 和 Edge type
# 创建运动员标签
CREATE TAG player(name string, age int);
# 创建球队标签
CREATE TAG team(name string);
# 创建X关注边
CREATE EDGE follow(degree int);
# 创建服役边
CREATE EDGE serve(start_year int, end_year int);
4. 插入数据
# 插入代表球员和球队的点
INSERT VERTEX player(name, age) VALUES "player100":("Tim Duncan", 42);
INSERT VERTEX player(name, age) VALUES "player101":("Tony Parker", 36);
INSERT VERTEX player(name, age) VALUES "player102":("LaMarcus Aldridge", 33);
INSERT VERTEX team(name) VALUES "team203":("Trail Blazers"), "team204":("Spurs");
# 插入代表球员和球队之间关系的边
INSERT EDGE follow(degree) VALUES "player101" -> "player100":(95);
INSERT EDGE follow(degree) VALUES "player101" -> "player102":(90);
INSERT EDGE follow(degree) VALUES "player102" -> "player100":(75);
INSERT EDGE serve(start_year, end_year) VALUES "player101" -> "team204":(1999, 2018),"player102" -> "team203":(2006, 2015);
5. 查询数据
- GO 语句可以根据指定的条件遍历数据库。GO语句从一个或多个点开始,沿着一条或多条边遍历,返回YIELD子句中指定的信息
- FETCH 语句可以获得点或边的属性
- LOOKUP 语句是基于索引的,和WHERE子句一起使用,查找符合特定条件的数据
- MATCH 语句是查询图数据最常用的,可以灵活的描述各种图模式,但是它依赖索引去匹配 NebulaGraph 中的数据模型,性能也还需要调优
# 从 VID 为player101的球员开始,沿着边follow找到连接的球员
GO FROM "player101" OVER follow YIELD id($$);
# 从 VID 为player101的球员开始,沿着边follow查找年龄大于或等于 35 岁的球员,并返回他们的姓名和年龄,同时重命名对应的列
GO FROM "player101" OVER follow WHERE properties($$).age >= 35 \
YIELD properties($$).name AS Teammate, properties($$).age AS Age;
# 查询 VID 为player100的球员的属性
FETCH PROP ON player "player100" YIELD properties(vertex);
6. 更新操作
# 用UPDATE修改 VID 为player100的球员的name属性,然后用FETCH语句检查结果
UPDATE VERTEX "player100" SET player.name = "Tim";
# 用UPDATE修改某条边的degree属性,然后用FETCH检查结果
UPDATE EDGE ON follow "player101" -> "player100" SET degree = 96;
FETCH PROP ON follow "player101" -> "player100" YIELD properties(edge);
# 用INSERT插入一个 VID 为player111的点,然后用UPSERT更新它
INSERT VERTEX player(name,age) VALUES "player111":("David West", 38);
UPSERT VERTEX "player111" SET player.name = "David", player.age = $^.player.age + 11 \
WHEN $^.player.name == "David West" AND $^.player.age > 20 \
YIELD $^.player.name AS Name, $^.player.age AS Age;
7. 删除点和边
# 删除点
DELETE VERTEX "player111", "team203";
# 删除边
DELETE EDGE follow "player101" -> "team204";
8. 使用索引
# 为 name 属性创建索引 player_index_1
CREATE TAG INDEX IF NOT EXISTS player_index_1 ON player(name(20));
# 重建索引确保能对已存在数据生效
REBUILD TAG INDEX player_index_1
# 使用 LOOKUP 语句检索点的属性
LOOKUP ON player WHERE player.name == "Tony Parker" \
YIELD properties(vertex).name AS name, properties(vertex).age AS age;
# 使用 MATCH 语句检索点的属性
MATCH (v:player{name:"Tony Parker"}) RETURN v;