IT袋

当前位置:主页 > 经验教程 > 建站编程 >

Nebula Graph概念

Nebula Graph概念介绍(3)

时间:2023-09-23 21:47:42 来源:IT袋 作者:苏晓敏
导读:Nebula Graph概念,常用命令 本文将使用下图的数据集演示基础操作的语法。 语法 1.3.4.1 创建和选择图空间 执行如下语句创建名为basketballplayer 的图空间。 (root@nebula) [(none

Nebula Graph概念

Nebula

常用命令

本文将使用下图的数据集演示基础操作的语法。

Nebula

语法

1.3.4.1 创建和选择图空间

执行如下语句创建名为basketballplayer
的图空间。

(root@nebula) [(none)]> CREATE SPACE basketballplayer(partition_num=15, replica_factor=1, vid_type=fixed_string(30));

选择图空间basketballplayer

(root@nebula) [(none)]> USE basketballplayer;

查看创建的图空间。

(root@nebula) [basketballplayer]>  SHOW SPACES;
+--------------------+
| Name               |
+--------------------+
| "basketballplayer" |
+--------------------+

1.3.4.2 创建 Tag 和 Edge type

Tag 和 Edge type 的作用,类似于关系型数据库中“点表”和“边表”的表结构。创建 Tag:player
和team
,以及 Edge type:follow
和serve

CREATE TAG player(name string, age int); 
CREATE TAG team(name string); 
CREATE EDGE follow(degree int); 
CREATE EDGE serve(start_year int, end_year int);

1.3.4.3 插入点和边

可以使用INSERT
语句,基于现有的 Tag 插入点,或者基于现有的 Edge type 插入边。

插入代表球员和球队的点。

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);

1.3.4.4 创建索引

MATCH
和LOOKUP
语句的执行都依赖索引,但是索引会导致写性能大幅降低(降低 90% 甚至更多)。请不要随意在生产环境中使用索引,除非很清楚使用索引对业务的影响。

必须为“已写入但未构建索引”的数据重建索引,否则无法在MATCH
和LOOKUP
语句中返回这些数据,参见 [重建索引] (https://docs.nebula-graph.com.cn/2.6.1/3.ngql-guide/14.native-index-statements/4.rebuild-native-index/)。

原生索引可以基于指定的属性查询数据,创建原生索引分为以下 3 种情况:

  • 创建 Tag/Edge type 索引。Tag 索引和 Edge type 索引应用于和Tag、Edge type 自身相关的查询,例如用LOOKUP
    查找有 Tagplayer
    的所有点。
  • 创建单属性索引。“属性索引”应用于基于属性的查询,例如基于属性age
    找到age == 19
    的所有的点。
  • 创建复合属性索引(遵循”最左匹配原则”)。

关于创建索引的详细内容可以查看 [CREATE INDEX] (https://docs.nebula-graph.com.cn/2.6.1/3.ngql-guide/14.native-index-statements/1.create-native-index/#tagedge_type)

1.3.4.4.1 为 TAG 创建索引

为 TAG team 的创建索引,需要重建索引确保对已存在数据生效,注意在重建索引之前我们等待 20s,因为新创建的索引并不会立刻生效,因为创建索引是异步实现的,Nebula Graph 需要在下一个心跳周期才能完成索引的创建。

# 为 Tag team 创建索引 team_index_1。 
CREATE TAG INDEX team_index_1 ON team(); 
# 重建索引确保能对已存在数据生效。
:sleep 20
REBUILD TAG INDEX team_index_1;

为 TAG player 的 name 属性创建单属性索引,为 name 和 age 属性创建复合属性索引。

# 为 Tag player 的 name 属性创建单属性索引 player_index_1。
# 索引长度为10。即只使用属性 name 的前 10 个字符来创建索引。
CREATE TAG INDEX player_index_1 ON player(name(20)); 
# 重建索引确保能对已存在数据生效。 
REBUILD TAG INDEX player_index_1;
# 为 Tag player 的 name 和 age 属性创建复合属性索引 player_index_2。
CREATE TAG INDEX player_index_2 ON player(name,age); 
# 重建索引确保能对已存在数据生效。 
:sleep 20
REBUILD TAG INDEX player_index_2;

新创建的索引并不会立刻生效,创建新的索引并尝试立刻使用(例如LOOKUP
或者REBUILD INDEX
)通常会失败(报错can’t find xxx in the space
)。因为创建步骤是异步实现的,Nebula Graph 要在下一个心跳周期才能完成索引的创建。可以使用如下方法之一:

  • 1.在SHOW TAG/EDGE INDEXES
    语句的结果中查找到新的索引。
  • 2.等待两个心跳周期,例如 20 秒。如果需要修改心跳间隔,请为所有配置文件修改参数heartbeat_interval_secs

1.3.4.4.2 为 EDGE type 创建索引

为 EDGE type 创建索引的方式和点相同,只是把关键字改成 EDGE 即可。

# 为 EDGE follow 的 degree 属性创建索引,并重建索引。
CREATE EDGE INDEX follow_index_1 on follow(degree);
:sleep 20
REBUILD EDGE INDEX follow_index_1;
# 为 EDGE serve 创建索引,并重建索引。
CREATE EDGE INDEX serve_index_1 on serve();
:sleep 20
REBUILD EDGE INDEX serve_index_1;
# 为 EDGE serve 创建复合属性索引,并重建索引。
CREATE EDGE INDEX serve_index_2 on serve(start_year,end_year);
:sleep 20
REBUILD EDGE INDEX serve_index_2;

1.3.4.5 查看索引

查看为 TAG player 和 team 创建的索引。

(root@nebula) [basketballplayer]> SHOW TAG INDEXES;
+------------------+----------+-----------------+
| Index Name       | By Tag   | Columns         |
+------------------+----------+-----------------+
| "player_index_1" | "player" | ["name"]        | # 单属性索引
| "player_index_2" | "player" | ["name", "age"] | # 复合属性索引
| "team_index_1"   | "team"   | []              | # TAG 索引
+------------------+----------+-----------------+

查看为 EDGE follow 和 serve 创建的索引。

(root@nebula) [basketballplayer]> SHOW EDGE INDEXES;
+------------------+----------+----------------------------+
| Index Name       | By Edge  | Columns                    |
+------------------+----------+----------------------------+
| "follow_index_1" | "follow" | ["degree"]                 | # 单属性索引
| "serve_index_1"  | "serve"  | []                         | # EDGE 索引
| "serve_index_2"  | "serve"  | ["start_year", "end_year"] | # 复合属性索引
+------------------+----------+----------------------------+

1.3.4.6 删除索引

删除 TAG player 的索引 player_index_2。

(root@nebula) [basketballplayer]> DROP TAG INDEX player_index_2;

删除 EDGE serve 的索引 serve_index_2。

(root@nebula) [basketballplayer]> DROP EDGE INDEX serve_index_2;

1.3.4.7 查询数据

查询数据主要有以下 4 种语句:

  • GO 语句可以根据指定的条件遍历数据库。GO
    语句从一个或多个点开始,沿着一条或多条边遍历,可以使用YIELD
    子句中指定的返回的信息。
  • FETCH 语句可以获得点或边的属性。
  • LOOKUP 语句是基于索引的,和WHERE
    子句一起使用,查找符合特定条件的数据。
  • MATCH 语句是查询图数据最常用的,与GO
    或LOOKUP
    等其他查询语句相比,MATCH
    的语法更灵活。MATCH 语句可以描述各种图模式,它依赖索引去匹配 Nebula Graph 中的数据模型。

1.3.4.7.1 GO 语句示例

从 TAG player 中 VID 为player101
的球员开始,沿着边follow
找到连接的球员。

(root@nebula) [basketballplayer]> GO FROM "player101" OVER follow;
+-------------+
| follow._dst |
+-------------+
| "player100" |
| "player102" |
+-------------+

1.3.4.7.2 FETCH 语句示例

查询 TAG player 中 VID 为player100
的球员的属性值。

(root@nebula) [basketballplayer]> FETCH PROP ON player "player100";
+----------------------------------------------------+
| vertices_                                          |
+----------------------------------------------------+
| ("player100" :player{age: 42, name: "Tim Duncan"}) |
+----------------------------------------------------+

获取连接 player102 和 team203 的边 serve 的所有属性值。

(root@nebula) [basketballplayer]> FETCH PROP ON serve "player102" -> "team203";
+-----------------------------------------------------------------------+
| edges_                                                                |
+-----------------------------------------------------------------------+
| [:serve "player102"->"team203" @0 {end_year: 2015, start_year: 2006}] |
+-----------------------------------------------------------------------+

1.3.4.7.3 LOOKUP 语句示例

列出 TAG player 的所有 VID。

(root@nebula) [basketballplayer]> LOOKUP ON player;
+-------------+
| VertexID    |
+-------------+
| "player100" |
| "player102" |
| "player103" |
+-------------+

列出 EDGE serve 所有边的起始点、目的点和 rank。

(root@nebula) [basketballplayer]> LOOKUP ON serve;
+-------------+-----------+---------+
| SrcVID      | DstVID    | Ranking |
+-------------+-----------+---------+
| "player101" | "team204" | 0       |
| "player102" | "team203" | 0       |
+-------------+-----------+---------+

LOOKUP 也可以基于 where 条件进行过滤,例如在 EDGE serve 中查询 start_year == 2006 的属性值。

(root@nebula) [basketballplayer]> LOOKUP ON serve where serve.start_year == 2006;
+-------------+-----------+---------+
| SrcVID      | DstVID    | Ranking |
+-------------+-----------+---------+
| "player102" | "team203" | 0       |
+-------------+-----------+---------+

1.3.4.7.4 MATCH 语句示例

通过 MATCH 语句分别查询 TAG player 和 team 的属性值。

# 查询 Tag 为 player 的点的属性值
(root@nebula) [basketballplayer]> MATCH (x:player) return x;
+-----------------------------------------------------------+
| x                                                         |
+-----------------------------------------------------------+
| ("player100" :player{age: 42, name: "Tim Duncan"})        |
| ("player101" :player{age: 36, name: "Tony Parker"})       |
| ("player102" :player{age: 33, name: "LaMarcus Aldridge"}) |
+-----------------------------------------------------------+
# 查询 Tag 为 team 的点的属性值
(root@nebula) [basketballplayer]> MATCH (x:team) return x;
+------------------------------------------+
| x                                        |
+------------------------------------------+
| ("team203" :team{name: "Trail Blazers"}) |
| ("team204" :team{name: "Spurs"})         |
+------------------------------------------+

也可以根据索引所在的属性进行查询,例如我们查询 TAG player 的 name 字段名为 Tony parker 的属性值。

(root@nebula) [basketballplayer]> MATCH (v:player{name:"Tony Parker"}) RETURN v;
+-----------------------------------------------------+
| v                                                   |
+-----------------------------------------------------+
| ("player101" :player{age: 36, name: "Tony Parker"}) |
+-----------------------------------------------------+

由于 TAG team 上的 name 属性并没有建立索引,因此无法根据 name 属性进行查询。

(root@nebula) [basketballplayer]> MATCH (v:team{name:'Spurs'}) RETURN v;
[ERROR (-1005)]: IndexNotFound: No valid index found

使用 MATCH 查询 EDGE serve 的属性值。

(root@nebula) [basketballplayer]> MATCH ()-[e:serve]-()  RETURN e;
+-----------------------------------------------------------------------+
| e                                                                     |
+-----------------------------------------------------------------------+
| [:serve "player101"->"team204" @0 {end_year: 2018, start_year: 1999}] |
| [:serve "player102"->"team203" @0 {end_year: 2015, start_year: 2006}] |
+-----------------------------------------------------------------------+

1.3.4.7.5 实际的查询例子

使用以下语句查询和 Tony Parker 有关的球员和球队。

(root@nebula) [basketballplayer]> MATCH p=(v:player{name:"Tony Parker"})-->(v2)   RETURN p
+-------------------------------------------------------------------------------------------------------------------------------------------+
| p                                                                                                                                         |
+-------------------------------------------------------------------------------------------------------------------------------------------+
| <("player101" :player{age: 36, name: "Tony Parker"})-[:serve@0 {end_year: 2018, start_year: 1999}]->("team204" :team{name: "Spurs"})>     |
| <("player101" :player{age: 36, name: "Tony Parker"})-[:follow@0 {degree: 95}]->("player100" :player{age: 42, name: "Tim Duncan"})>        |
| <("player101" :player{age: 36, name: "Tony Parker"})-[:follow@0 {degree: 90}]->("player102" :player{age: 33, name: "LaMarcus Aldridge"})> |
+-------------------------------------------------------------------------------------------------------------------------------------------+

和 Tony Parker 有关系的球员和球队在下图中用绿色方框标识。

Nebula

1.3.4.8 修改点和边

用户可以使用UPDATE
语句或UPSERT
语句修改现有数据。UPSERT
是UPDATE
和INSERT
的结合体。当使用UPSERT
更新一个点或边,如果它不存在,数据库会自动插入一个新的点或边。

首先查询 TAG player 现在的属性值。

(root@nebula) [basketballplayer]> match (n:player) return n;
+-----------------------------------------------------------+
| n                                                         |
+-----------------------------------------------------------+
| ("player100" :player{age: 42, name: "Tim"})               |
| ("player101" :player{age: 36, name: "Tony Parker"})       |
| ("player102" :player{age: 33, name: "LaMarcus Aldridge"}) |
+-----------------------------------------------------------+

用UPDATE
修改 VID 为player100
的球员的name
属性,然后用FETCH
语句检查结果。

(root@nebula) [basketballplayer]> UPDATE VERTEX "player100" SET player.name = "Tim";
(root@nebula) [basketballplayer]> FETCH PROP ON player "player100";
+---------------------------------------------+
| vertices_                                   |
+---------------------------------------------+
| ("player100" :player{age: 42, name: "Tim"}) |
+---------------------------------------------+

执行UPSERT
语句,分别对已存在的 player101 和未存在的 player103 进行操作,通过 MATCH 查询可以看到在UPSERT
修改了原本 player101 的值,新插入的 player103。

(root@nebula) [basketballplayer]> UPSERT VERTEX "player101" SET player.name = "CRIS", player.age = 18;
(root@nebula) [basketballplayer]> UPSERT VERTEX "player103" SET player.name = "THOMAS", player.age = 20;
(root@nebula) [basketballplayer]> match (n:player) return n;
+-----------------------------------------------------------+
| n                                                         |
+-----------------------------------------------------------+
| ("player101" :player{age: 18, name: "CRIS"})              |
| ("player100" :player{age: 42, name: "Tim"})               |
| ("player102" :player{age: 33, name: "LaMarcus Aldridge"}) |
| ("player103" :player{age: 20, name: "THOMAS"})            |
+-----------------------------------------------------------+

1.3.4.9 删除点和边

删除点。

nebula> DELETE VERTEX "player101";

删除边。

nebula> DELETE EDGE follow "player101" -> "team204";

1.3.4.10 删除 TAG 和 EDGE

删除 TAG/EDGE 前要确保 TAG/EDGE 不包含任何索引,否则DROP TAG
时会报冲突错误[ERROR (-8)]: Conflict!

删除 TAG。

# 删除 TAG 的索引
DROP TAG INDEX player_index_1;
DROP TAG INDEX team_index_1;
# 删除 TAG 
DROP TAG player;
DROP TAG team;

删除 EDGE。

# 删除 EDGE 的索引
DROP EDGE INDEX follow_index_1
DROP EDGE INDEX serve_index_1
# 删除 EDGE 
DROP EDGE follow;
DROP EDGE serve;

以上分享的Nebula、Graph概念介绍的全文内容,IT袋网[www.itdai.com]希望对网友有所帮助!

相关阅读

  • oracle数据库冷备份详细教程步骤 oracle怎么进行冷备份

    oracle数据库冷备份详细教程步骤 oracle怎么进行冷备份

    一篇关于oracle数据库冷备份详细教程步骤的电脑小知识,接下来就是全面介绍。 冷备份是指在数据库关闭的情况下进行的备份,因此冷备份也被称为离线备份。 在Oracle数据库中,进行冷备份涉

  • cURL是什么意思 cURL支持的通信协议有哪些?

    cURL是什么意思 cURL支持的通信协议有哪些?

    cURL是什么意思?curl是什么命令? cURL命令是一个利用URL语法在命令行下工作的文件传输工具,1998年首次发行。它支持文件上传和下载,所以是综合传输工具,但按传统,习惯称cURL为下载工具

  • vSphere之VMkernel网络层

    vSphere之VMkernel网络层

    今日重点为您介绍vSphere之VMkernel网络层方面的内容,请看下面详细的介绍。 VMkernel 网络层用于VSS(标准交换机),提供与主机的连接,并处理 vSphere vMotion、IP 存储、Fault Tolerance、vSAN 等其他服

  • 服务器CDN是什么? 服务器CDN的优缺点有哪些

    服务器CDN是什么? 服务器CDN的优缺点有哪些

    今天为大家介绍服务器CDN是什么的电脑方面的小经验,接下来就是全面介绍。 随着互联网的普及和发展,越来越多的网站和应用程序需要大量的带宽和处理能力,以支持全球各地用户的访问需