nebula graph操作手册
1. 摘抄网址
官网:Nebula Graph Database 手册 (nebula-graph.com.cn)
论坛:https://discuss.nebula-graph.com.cn/
spark-connector: https://docs.nebula-graph.com.cn/2.6.1/nebula-spark-connector/
集群版:192.168.11.73,192.168.11.74,192.168.11.75
http://192.168.11.75:7001/ HOST: 192.168.11.75:9669 用户名:root 密码:123
单机版: 192.168.13.82
http://192.168.13.82:7001/ HOST: 192.168.3.82:9669 用户名:root 密码:123
2. nebula graph简介
2.1 什么是Nebula Graph
Nebula Graph是一款开源的、分布式的、易扩展的原生图数据库,能够承载数千亿个点和数万亿条边的超大规模数据集,并且提供毫秒级查询。
图数据库是专门存储庞大的图形网络并从中检索信息的数据库。它可以将图中的数据高效存储为点(Vertex)和边(Edge),还可以将属性(Property)附加到点和边上。
图数据库适合存储大多数从现实抽象出的数据类型。世界上几乎所有领域的事物都有内在联系,像关系型数据库这样的建模系统会提取实体之间的关系,并将关系单独存储到表和列中,而实体的类型和属性存储在其他列甚至其他表中,这使得数据管理费时费力。
Nebula Graph作为一个典型的图数据库,可以将丰富的关系通过边及其类型和属性自然地呈现。
2.1.2 Nebula Graph的优势
开源 , 高性能 , 易扩展 , 易开发 , 高可靠访问控制 , 生态多样化 , 兼容openCypher 查询语言 , 灵活数据建模 , 广受欢迎
2.1.3 适用场景
欺诈检测 , 实时推荐 , 知识图谱 , 社交网络
3. 下载与安装nebula graph
此处只讲物理机安装,docker安装请参照官网https://docs.nebula-graph.com.cn/2.6.1/2.quick-start/2.install-nebula-graph/
3.1 下载安装包
3.1.1 URL格式如下:
//Centos 7
https://oss-cdn.nebula-graph.com.cn/package/<release_version>/nebula-graph-<release_version>.el7.x86_64.rpm
//Centos 8
https://oss-cdn.nebula-graph.com.cn/package/<release_version>/nebula-graph-<release_version>.el8.x86_64.rpm
//Ubuntu 1604
https://oss-cdn.nebula-graph.com.cn/package/<release_version>/nebula-graph-<release_version>.ubuntu1604.amd64.deb
//Ubuntu 1804
https://oss-cdn.nebula-graph.com.cn/package/<release_version>/nebula-graph-<release_version>.ubuntu1804.amd64.deb
//Ubuntu 2004
https://oss-cdn.nebula-graph.com.cn/package/<release_version>/nebula-graph-<release_version>.ubuntu2004.amd64.deb
</release_version></release_version></release_version></release_version></release_version></release_version></release_version></release_version></release_version></release_version>
例如要下载适用于 Centos 7.5
的 2.6.1
安装包:
wget https://oss-cdn.nebula-graph.com.cn/package/2.6.1/nebula-graph-2.6.1.el7.x86_64.rpm
wget https://oss-cdn.nebula-graph.com.cn/package/2.6.1/nebula-graph-2.6.1.el7.x86_64.rpm.sha256sum.txt
下载适用于 ubuntu 1804
的 2.6.1
安装包:
wget https://oss-cdn.nebula-graph.com.cn/package/2.6.1/nebula-graph-2.6.1.ubuntu1804.amd64.deb
wget https://oss-cdn.nebula-graph.com.cn/package/2.6.1/nebula-graph-2.6.1.ubuntu1804.amd64.deb.sha256sum.txt
3.1.2 查看虚拟机内核版本
lsb_release -a
=>
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 18.04.1 LTS
Release: 18.04
Codename: bionic
3.1.3 下地址拼接
wget https://oss-cdn.nebula-graph.com.cn/package/2.6.1/nebula-graph-2.6.1.ubuntu1804.amd64.deb
3.2 安装Nebula Graph
3.2.1 在默认路径下安装
sudo dpkg -i nebula-graph-2.6.1.ubuntu1804.amd64.deb
如果不设置安装路径,默认安装路径为 /usr/local/nebula/
3.2.2 指定安装路径
sudo dpkg -i --instdir==/home/intellif/nebula nebula-graph-2.6.1.ubuntu1804.amd64.deb
指定安装目录为 /home/intellif/nebula
3.3 修改配置文件
cd /usr/local/nebula/etc
修改:nebula-graphd.conf,nebula-metad.conf,nebula-storaged.conf 将文件中127.0.0.1/0.0.0.0换成本地ip地址192.168.13.82
须在配置文件中使用真实的 IP 地址。否则某些情况下127.0.0.1/0.0.0.0无法正确解析
一定修改ip地址,不然会导致后续写入可以成功但是读取报错。使用spark-connector始终无法读取Nebula Graph数据,抛出ExecuteFailedException: Execute failed: no parts succeed, error message: Unable to activate object
3.4 卸载DEB 包安装的 Nebula Graph
- 使用如下命令查看 Nebula Graph 版本。
$ dpkg -l | grep "nebula"
返回类似如下结果。
ii nebula-graph 2.6.1 amd64 Nebula Package built using CMake
- 使用如下命令卸载 Nebula Graph。
sudo dpkg -r <nebula_version>
</nebula_version>
例如:
sudo dpkg -r nebula-graph
- 删除安装目录。
4. 启动Nebula Graph服务
Nebula Graph使用脚本 nebula.service
管理服务,包括启动、停止、重启、中止和查看。
nebula.service
的默认路径是 /usr/local/nebula/scripts
,如果修改过安装路径,请使用实际路径。
语法:
$ sudo /usr/local/nebula/scripts/nebula.service
[-v] [-c <config_file_path>]
<start|stop|restart|kill|status>
<metad|graphd|storaged|all>
</metad|graphd|storaged|all></start|stop|restart|kill|status></config_file_path>
参数说明 -v
显示详细调试信息。 -c
指定配置文件路径,默认路径为 /usr/local/nebula/etc/
start
启动服务。 stop
停止服务。 restart
重启服务。 kill
中止服务。 status
查看服务状态。 metad
管理Meta服务。 graphd
管理Graph服务。 storaged
管理Storage服务。 all
管理所有服务。
4.1 启动所有服务
sudo /usr/local/nebula/scripts/nebula.service start all
4.2 停止所有服务
sudo /usr/local/nebula/scripts/nebula.service stop all
4.3 查看所有服务
sudo /usr/local/nebula/scripts/nebula.service status all
5. 连接Nebula Graph服务
5.1 前提条件
- Nebula Graph服务已启动。
- 运行Nebula Console的机器和运行Nebula Graph的服务器网络互通。
5.2 操作步骤
- 在Nebula Console下载页面,确认需要的版本,单击 Assets。
- 在 Assets区域找到机器运行所需的二进制文件,下载文件到机器上 下载: nebula-console-linux-amd64-v2.6.1
- (可选)为方便使用,重命名文件为
nebula-console
。 - 在运行Nebula Console的机器上执行如下命令,为用户授予nebula-console文件的执行权限。
- 在命令行界面中,切换工作目录至nebula-console文件所在目录。
- 执行如下命令连接Nebula Graph。
./nebula-console -addr <ip> -port <port> -u <username> -p <password> [-t 120] [-e "nGQL_statement" | -f filename.nGQL]
</password></username></port></ip>
参数说明 -h
显示帮助菜单。 -addr
设置要连接的graphd服务的IP地址。默认地址为127.0.0.1。 -port
设置要连接的graphd服务的端口。默认端口为9669。 -u/-user
设置Nebula Graph账号的用户名。未启用身份认证时,可以使用任意已存在的用户名(默认为 root
)。 -p/-password
设置用户名对应的密码。未启用身份认证时,密码可以填写任意字符。 -t/-timeout
设置整数类型的连接超时时间。单位为秒,默认值为120。 -e/-eval
设置字符串类型的nGQL语句。连接成功后会执行一次该语句并返回结果,然后自动断开连接。 -f/-file
设置存储nGQL语句的文件的路径。连接成功后会执行该文件内的nGQL语句并返回结果,执行完毕后自动断开连接。
例如:
./nebula-console -addr 192.168.13.82 -port 9669 -u root -p 123 -t 120
连接后可以使用 ./nebula-console --help
命令获取所有参数的说明,也可以在项目仓库找到更多说明。
6. 安装Nebula Graph Studio
Nebula Graph Studio(简称 Studio)是一款可以通过 Web 访问的图数据库开源可视化工具,搭配 Nebula Graph 内核使用,提供构图、数据导入、编写 nGQL 查询、图探索等一站式服务。
6.1 tar 包部署 Studio
6.1.1 前提条件
在部署 tar 包安装的 Studio 之前,用户需要确认以下信息:
- Nebula Graph 服务已经部署并启动。详细信息,参考Nebula Graph安装部署。
- 使用的 Linux 上安装有版本为 v10.12.0 以上的 Node.js。 linux下npm和node的升级 安装 npm nodejs sudo npm i -g npm
1. 查看版本
npm -v
6.14.2
node -v
v8.11.2
1. . npm升级
升级到最新版本
sudo npm i -g npm
升级到指定版本
sudo npm i -g npm@8.11.2
1. node升级(不可以升级到最新版本 v17.0.1)
sudo npm i -g n
安装指定版本
sudo n v14.18.1
* 确保在安装开始前,以下端口处于未被使用状态。
端口号说明7001Studio提供的web服务8080Nebula-http-gateway,Client的HTTP服务
6.1.2 安装
- 根据需要下载 tar 包,建议选择最新版本。安装包Studio 版本nebula-graph-studio-3.1.0.x86_64.tar.gz3.1.0
- 使用
tar -xvf
解压 tar 包。
tar -xvf nebula-graph-studio-3.1.0.x86_64.tar.gz
6.1.3 部署
- 部署 nebula-http-gateway 并启动。
$ cd nebula-http-gateway
$ nohup ./nebula-httpd &
查看nebula-httpd服务是否启动成功: ps -ef | grep nebula-httpd 如果没有启动成功则页面会显示: 请求错误:504 Gateway Timeout
2. 部署 nebula-graph-studio 并启动。
$ cd nebula-graph-studio
$ npm run start
- 启动成功后,在浏览器地址栏输入
http://ip address:7001
。
如果在浏览器窗口中能看到以下登录界面,表示已经成功部署并启动 Studio。
6.2 停止服务
用户可以采用 kill pid
的方式来关停服务:
kill $(lsof -t -i :8080) # stop nebula-http-gateway
cd nebula-graph-studio
npm run stop # stop nebula-graph-studio
6.3 连接数据库
6.3.1 Host
填写 Nebula Graph 的 Graph 服务本机 IP 地址及端口。格式为 ip:port
。如果端口未修改,则使用默认端口 9669
。
即使 Nebula Graph 数据库与 Studio 部署在同一台机器上,用户也必须在 Host 字段填写这台机器的本机 IP 地址,而不是 127.0.0.1
或者 localhost
。
6.3.2 用户名和密码
根据 Nebula Graph 的身份验证设置填写登录账号和密码。
- 如果未启用身份验证,可以填写默认用户名
root
和任意密码。 - 如果已启用身份验证,但是未创建账号信息,用户只能以 GOD 角色登录,必须填写
root
及对应的密码nebula
。 - 如果已启用身份验证,同时又创建了不同的用户并分配了角色,不同角色的用户使用自己的账号和密码登录。
例如:
Host: 192.168.13.82:9669
用户名:root
密码: 123456
6.4 部署多机集群
6.4.1 部署方案
准备5台用于部署集群的机器
机器名称IP 地址graphd 进程数量storaged 进程数量metad 进程数量A192.168.10.111111B192.168.10.112111C192.168.10.113111D192.168.10.11411-E192.168.10.11511-
6.4.2 手动部署流程
- 安装nebula Graph 在集群的每台服务器上都安装nebula Graph,安装后暂不需要启动服务。
- 修改配置文件 修改每个服务器上的nebula Graph配置文件。 Nebula Graph的所有配置文件均位于安装目录的etc目录内,包括
nebula-graphd.conf
、nebula-metad.conf
和nebula-storaged.conf
,用户可以只修改所需服务的配置文件。各个机器需要修改的配置文件如下。机器名称待修改配置文件Anebula-graphd.conf
、nebula-storaged.conf
、nebula-metad.conf
Bnebula-graphd.conf
、nebula-storaged.conf
、nebula-metad.conf
Cnebula-graphd.conf
、nebula-storaged.conf
、nebula-metad.conf
Dnebula-graphd.conf
、nebula-storaged.conf
Enebula-graphd.conf
、nebula-storaged.conf
机器A的配置:
- nebula-graphd.conf
########## networking ##########
Comma separated Meta Server Addresses
--meta_server_addrs=192.168.10.111:9559,192.168.10.112:9559,192.168.10.113:9559
Local IP used to identify the nebula-graphd process.
Change it to an address other than loopback if the service is distributed or
will be accessed remotely.
--local_ip=192.168.10.111
Network device to listen on
--listen_netdev=any
Port to listen on
--port=9669
- nebula-storaged.conf
########## networking ##########
Comma separated Meta server addresses
--meta_server_addrs=192.168.10.111:9559,192.168.10.112:9559,192.168.10.113:9559
Local IP used to identify the nebula-storaged process.
Change it to an address other than loopback if the service is distributed or
will be accessed remotely.
--local_ip=192.168.10.111
Storage daemon listening port
--port=9779
- nebula-metad.conf
########## networking ##########
Comma separated Meta Server addresses
--meta_server_addrs=192.168.10.111:9559,192.168.10.112:9559,192.168.10.113:9559
Local IP used to identify the nebula-metad process.
Change it to an address other than loopback if the service is distributed or
will be accessed remotely.
--local_ip=192.168.10.111
Meta daemon listening port
--port=9559
机器 B 配置
nebula-graphd.conf
########## networking ##########
Comma separated Meta Server Addresses
--meta_server_addrs=192.168.10.111:9559,192.168.10.112:9559,192.168.10.113:9559
Local IP used to identify the nebula-graphd process.
Change it to an address other than loopback if the service is distributed or
will be accessed remotely.
--local_ip=192.168.10.112
Network device to listen on
--listen_netdev=any
Port to listen on
--port=9669
nebula-storaged.conf
########## networking ##########
Comma separated Meta server addresses
--meta_server_addrs=192.168.10.111:9559,192.168.10.112:9559,192.168.10.113:9559
Local IP used to identify the nebula-storaged process.
Change it to an address other than loopback if the service is distributed or
will be accessed remotely.
--local_ip=192.168.10.112
Storage daemon listening port
--port=9779
nebula-metad.conf
########## networking ##########
Comma separated Meta Server addresses
--meta_server_addrs=192.168.10.111:9559,192.168.10.112:9559,192.168.10.113:9559
Local IP used to identify the nebula-metad process.
Change it to an address other than loopback if the service is distributed or
will be accessed remotely.
--local_ip=192.168.10.112
Meta daemon listening port
--port=9559
机器 C 配置
nebula-graphd.conf
########## networking ##########
Comma separated Meta Server Addresses
--meta_server_addrs=192.168.10.111:9559,192.168.10.112:9559,192.168.10.113:9559
Local IP used to identify the nebula-graphd process.
Change it to an address other than loopback if the service is distributed or
will be accessed remotely.
--local_ip=192.168.10.113
Network device to listen on
--listen_netdev=any
Port to listen on
--port=9669
nebula-storaged.conf
########## networking ##########
Comma separated Meta server addresses
--meta_server_addrs=192.168.10.111:9559,192.168.10.112:9559,192.168.10.113:9559
Local IP used to identify the nebula-storaged process.
Change it to an address other than loopback if the service is distributed or
will be accessed remotely.
--local_ip=192.168.10.113
Storage daemon listening port
--port=9779
nebula-metad.conf
########## networking ##########
Comma separated Meta Server addresses
--meta_server_addrs=192.168.10.111:9559,192.168.10.112:9559,192.168.10.113:9559
Local IP used to identify the nebula-metad process.
Change it to an address other than loopback if the service is distributed or
will be accessed remotely.
--local_ip=192.168.10.113
Meta daemon listening port
--port=9559
机器 D 配置
nebula-graphd.conf
########## networking ##########
Comma separated Meta Server Addresses
--meta_server_addrs=192.168.10.111:9559,192.168.10.112:9559,192.168.10.113:9559
Local IP used to identify the nebula-graphd process.
Change it to an address other than loopback if the service is distributed or
will be accessed remotely.
--local_ip=192.168.10.114
Network device to listen on
--listen_netdev=any
Port to listen on
--port=9669
nebula-storaged.conf
########## networking ##########
Comma separated Meta server addresses
--meta_server_addrs=192.168.10.111:9559,192.168.10.112:9559,192.168.10.113:9559
Local IP used to identify the nebula-storaged process.
Change it to an address other than loopback if the service is distributed or
will be accessed remotely.
--local_ip=192.168.10.114
Storage daemon listening port
--port=9779
机器 E 配置
nebula-graphd.conf
########## networking ##########
Comma separated Meta Server Addresses
--meta_server_addrs=192.168.10.111:9559,192.168.10.112:9559,192.168.10.113:9559
Local IP used to identify the nebula-graphd process.
Change it to an address other than loopback if the service is distributed or
will be accessed remotely.
--local_ip=192.168.10.115
Network device to listen on
--listen_netdev=any
Port to listen on
--port=9669
nebula-storaged.conf
########## networking ##########
Comma separated Meta server addresses
--meta_server_addrs=192.168.10.111:9559,192.168.10.112:9559,192.168.10.113:9559
Local IP used to identify the nebula-storaged process.
Change it to an address other than loopback if the service is distributed or
will be accessed remotely.
--local_ip=192.168.10.115
Storage daemon listening port
--port=9779
6.4.3 启动集群
依次启动 各个服务器上的对应进程。
机器名称待启动的进程Agraphd、storaged、metadBgraphd、storaged、metadCgraphd、storaged、metadDgraphd、storagedEgraphd、storaged
启动 Nebula Graph 进程的命令如下:
sudo /usr/local/nebula/scripts/nebula.service start <metad|graphd|storaged>
</metad|graphd|storaged>
6.4.4 检查集群
安装原生CLI客户端Nebula Console,然后连接任何一个已启动graphd进程的机器
$ ./nebula-console --addr 192.168.10.111 --port 9669 -u root -p nebula
2021/05/25 01:41:19 [INFO] connection pool is initialized successfully
Welcome to Nebula Graph!
> SHOW HOSTS;
+------------------+------+----------+--------------+----------------------+------------------------+
| Host | Port | Status | Leader count | Leader distribution | Partition distribution |
+------------------+------+----------+--------------+----------------------+------------------------+
| "192.168.10.111" | 9779 | "ONLINE" | 0 | "No valid partition" | "No valid partition" |
| "192.168.10.112" | 9779 | "ONLINE" | 0 | "No valid partition" | "No valid partition" |
| "192.168.10.113" | 9779 | "ONLINE" | 0 | "No valid partition" | "No valid partition" |
| "192.168.10.114" | 9779 | "ONLINE" | 0 | "No valid partition" | "No valid partition" |
| "192.168.10.115" | 9779 | "ONLINE" | 0 | "No valid partition" | "No valid partition" |
| "Total" | | | 0 | | |
+------------------+------+----------+--------------+----------------------+------------------------+
7. 常用命令 nGQL
7.1 创建和选择图空间
7.1.1 创建
CREATE SPACE [IF NOT EXISTS] <graph_space_name> (
[partition_num = <partition_number>,]
[replica_factor = <replica_number>,]
vid_type = {FIXED_STRING(<n>) | INT[64]}
)
[ON <group_name>]
[COMMENT = '<comment>'];
</comment></group_name></n></replica_number></partition_number></graph_space_name>
参数说明 IF NOT EXISTS
检测待创建的图空间是否存在,只有不存在时,才会创建图空间。仅检测图空间的名称,不会检测具体属性。 <graph_space_name></graph_space_name>
在Nebula Graph实例中唯一标识一个图空间。图空间名称由大小写英文字母、数字或下划线组成,区分大写小,且不可使用
关键字和保留字 partition_num
指定图空间的分片数量。建议设置为5倍的集群硬盘数量。例如集群中有3个硬盘,建议设置15个分片。默认值为100。 replica_factor
指定每个分片的副本数量。建议在生产环境中设置为3,在测试环境中设置为1。由于需要基于多数表决,副本数量必须是
奇数
。默认值为1。 vid_type
必选参数。指定点ID的数据类型。可选值为 FIXED_STRING(<n>)</n>
INT64
INT
等同于 INT64
FIXED_STRING(<n>)</n>
表示数据类型为字符串,最大长度为 N
,超出长度会报错; INT64
表示数据类型为整数。 ON <group_name></group_name>
指定图空间所属的Group。详情请参见
Group&Zone COMMENT
图空间的描述。最大为256字节。默认无描述。
备注 :
- 如果将副本数设置为1,用户将无法使用BALANCE命令为Nebula Graph的存储服务平衡负载或扩容。
- 在Nebula Graph 1.x中,VID的类型只能为
INT64
,不支持字符型;在Nebula Graph 2.x中, VID的类型支持INT64
和FIXED_STRING(<n>)</n>
。请在创建图空间时指定VID类型,使用INSERT
语句时也需要保持一致,否则会报错VID类型不匹配Wrong vertex id type: 1001
。 - VID最大长度必须为
N
,不可任意长度;超过该长度也会报错The VID must be a 64-bit integer or a string fitting space vertex id length limit.
。
例如:
CREATE SPACE basketballplayer(partition_num=15,replica_factor=1,vid_type=fixed_string(30));
create space test1(partition_num=20,replica_factor=1,vid_type=fixed_string(30)) comment = '测试1';
7.1.2 使用
USE <graph_space_name>;
例如:use test1;
</graph_space_name>
7.1.3 显示所有space
SHOW SPACES;
7.1.4 显示space的详细信息
DESC[RIBE] SPACE <graph_space_name>;
例如: desc space test1
</graph_space_name>
7.1.5 删除space
DROP SPACE [IF EXISTS] <graph_space_name>;
例如: drop space if exists test1;
</graph_space_name>
IF EXISTS
关键字可以检测待删除的图空间是否存在,只有存在时,才会删除图空间。
DROP SPACE 语句不会立刻删除硬盘上对应图空间的目录和文件,请使用
USE 语句指定其他任意图空间,然后执行
SUBMIT JOB COMPACT
7.2 顶点TAG
7.2.1 创建
创建Tag前,需要先用 USE
语句指定工作空间。
CREATE TAG [IF NOT EXISTS] <tag_name>
(
<prop_name> <data_type> [NULL | NOT NULL] [DEFAULT <default_value>] [COMMENT '<comment>']
[{, <prop_name> <data_type> [NULL | NOT NULL] [DEFAULT <default_value>] [COMMENT '<comment>']} ...]
)
[TTL_DURATION = <ttl_duration>]
[TTL_COL = <prop_name>]
[COMMENT = '<comment>'];
</comment></prop_name></ttl_duration></comment></default_value></data_type></prop_name></comment></default_value></data_type></prop_name></tag_name>
参数说明 IF NOT EXISTS
检测待创建的Tag是否存在,只有不存在时,才会创建Tag。仅检测Tag的名称,不会检测具体属性。 <tag_name></tag_name>
每个图空间内的Tag必须是唯一的。Tag名称设置后无法修改。Tag名称由大小写英文字母、数字或下划线组成,区分大写小,且不可使用
关键字和保留字 <prop_name></prop_name>
属性名称。每个Tag中的属性名称必须唯一。属性的命名规则与Tag相同。 <data_type></data_type>
以及
日期与时间 NULL \| NOT NULL
指定属性值是否支持为 NULL
。默认值为 NULL
DEFAULT
指定属性的默认值。默认值可以是一个文字值或Nebula Graph支持的表达式。如果插入点时没有指定某个属性的值,则使用默认值。 COMMENT
对单个属性或Tag的描述。最大为256字节。默认无描述。 TTL_DURATION
指定属性存活时间。超时的属性将会过期。属性值和时间戳差值之和如果小于当前时间戳,属性就会过期。默认值为 0
,表示属性永不过期。 TTL_COL
指定要设置存活时间的属性。属性的数据类型必须是 int
或者 timestamp
。一个Tag只能指定一个字段为 TTL_COL
。更多TTL的信息请参见
TTL
例如:
CREATE TAG IF NOT EXISTS player(name string, age int);
创建没有属性的Tag
CREATE TAG IF NOT EXISTS no_property();
创建包含默认值的Tag
CREATE TAG IF NOT EXISTS player_with_default(name string, age int DEFAULT 20);
对字段create_time设置TTL为100秒
CREATE TAG IF NOT EXISTS woman(name string, age int,married bool, salary double, create_time timestamp) TTL_DURATION = 100, TTL_COL = "create_time";
7.2.2 删除
前提条件
- 登录的用户必须拥有对应权限才能执行
DROP TAG
语句。详情请参见内置角色权限。 - 确保Tag不包含任何索引,否则
DROP TAG
时会报冲突错误[ERROR (-8)]: Conflict!
。删除索引请参见drop index。
语法
DROP TAG [IF EXISTS] <tag_name>;
</tag_name>
IF EXISTS
:检测待删除的Tag是否存在,只有存在时,才会删除Tag。tag_name
:指定要删除的Tag名称。一次只能删除一个Tag。
示例
nebula> CREATE TAG IF NOT EXISTS test(p1 string, p2 int);
nebula> DROP TAG test;
7.2.3 修改
ALTER TAG
语句可以修改Tag的结构。例如增删属性、修改数据类型,也可以为属性设置、修改TTL(Time-To-Live)。
前提条件:
- 登录的用户必须拥有对应权限才能执行
ALTER TAG
语句。详情请参见内置角色权限。 - 确保要修改的属性不包含索引,否则
ALTER TAG
时会报冲突错误[ERROR (-8)]: Conflict!
。删除索引请参见drop index。
语法:
ALTER TAG <tag_name>
<alter_definition> [[, alter_definition] ...]
[ttl_definition [, ttl_definition] ... ]
[COMMENT = '<comment>'];
alter_definition:
| ADD (prop_name data_type)
| DROP (prop_name)
| CHANGE (prop_name data_type)
ttl_definition:
TTL_DURATION = ttl_duration, TTL_COL = prop_name
</comment></alter_definition></tag_name>
tag_name
:指定要修改的Tag名称。一次只能修改一个Tag。请确保要修改的Tag在当前工作空间中存在,否则会报错。- 可以在一个
ALTER TAG
语句中使用多个ADD
、DROP
和CHANGE
子句,子句之间用英文逗号(,)分隔。
示例:
nebula> CREATE TAG IF NOT EXISTS t1 (p1 string, p2 int);
nebula> ALTER TAG t1 ADD (p3 int, p4 string);
nebula> ALTER TAG t1 TTL_DURATION = 2, TTL_COL = "p2";
nebula> ALTER TAG t1 COMMENT = 'test1';
7.2.4 显示所有tag
SHOW TAGS
语句显示当前图空间内的所有Tag名称。
执行 SHOW TAGS
语句不需要任何权限,但是返回结果由登录的用户权限决定。
语法:
SHOW TAGS;
7.2.5 显示tag的详细
DESCRIBE TAG
显示指定Tag的详细信息,例如字段名称、数据类型等。
前提条件:
登录的用户必须拥有对应权限才能执行 DESCRIBE TAG
语句。详情请参见内置角色权限。
语法:
DESC[RIBE] TAG <tag_name>;
</tag_name>
DESCRIBE
可以缩写为 DESC
。
示例:
DESCRIBE TAG player;
7.2.6 删除tag
DELETE TAG
语句可以删除指定点上的指定Tag。
点可以有一个或多个Tag。
- 如果某个点只有一个Tag,删除这个点上的Tag后,用户就 无法访问这个点,下次Compaction操作时会删除该点,但点上的边仍然存在。
- 如果某个点有多个Tag,删除其中一个Tag,仍然可以访问这个点,但是 无法访问这个点上已删除Tag所定义的所有属性。
前提条件:
登录的用户必须拥有对应权限才能执行 DELETE TAG
语句。详情请参见内置角色权限。
语法:
DELETE TAG <tag_name_list> FROM <vid>;
</vid></tag_name_list>
tag_name_list
:指定Tag名称。多个Tag用英文逗号(,)分隔,也可以用*
表示所有Tag。VID
:指定要删除Tag的点ID。
示例:
nebula> CREATE TAG IF NOT EXISTS test1(p1 string, p2 int);
nebula> CREATE TAG IF NOT EXISTS test2(p3 string, p4 int);
nebula> INSERT VERTEX test1(p1, p2),test2(p3, p4) VALUES "test":("123", 1, "456", 2);
nebula> FETCH PROP ON * "test";
+------------------------------------------------------------+
| vertices_ |
+------------------------------------------------------------+
| ("test" :test2{p3: "456", p4: 2} :test1{p1: "123", p2: 1}) |
+------------------------------------------------------------+
nebula> DELETE TAG test1 FROM "test";
nebula> FETCH PROP ON * "test";
+-----------------------------------+
| vertices_ |
+-----------------------------------+
| ("test" :test2{p3: "456", p4: 2}) |
+-----------------------------------+
nebula> DELETE TAG * FROM "test";
nebula> FETCH PROP ON * "test";
7.2.7 增加和删除标签
在openCypher中,有增加标签( SET label
)和移除标签( REMOVE label
)的功能,可以用于加速查询或者标记过程。
在Nebula Graph中,可以通过Tag变相实现相同操作,创建Tag并将Tag插入到已有的点上,就可以根据Tag名称快速查找点,也可以通过 DELETE TAG
删除某些点上不再需要的Tag。
Caution
请确保点上已经有另一个Tag,否则删除点上最后一个Tag时,会导致点也被删除。
示例:
例如在basketballplayer数据集中,部分篮球运动员同时也是球队股东,可以为股东Tag shareholder
创建索引,方便快速查找。如果不再是股东,可以通过 DELETE TAG
语句删除相应运动员的股东Tag。
//创建股东Tag和索引
nebula> CREATE TAG IF NOT EXISTS shareholder();
nebula> CREATE TAG INDEX IF NOT EXISTS shareholder_tag on shareholder();
//为点添加Tag
nebula> INSERT VERTEX shareholder() VALUES "player100":();
nebula> INSERT VERTEX shareholder() VALUES "player101":();
//快速查询所有股东
nebula> MATCH (v:shareholder) RETURN v;
+---------------------------------------------------------------------+
| v |
+---------------------------------------------------------------------+
| ("player100" :player{age: 42, name: "Tim Duncan"} :shareholder{}) |
| ("player101" :player{age: 36, name: "Tony Parker"} :shareholder{}) |
+---------------------------------------------------------------------+
nebula> LOOKUP ON shareholder;
+-------------+
| VertexID |
+-------------+
| "player100" |
| "player101" |
+-------------+
//如果player100不再是股东
nebula> DELETE TAG shareholder FROM "player100";
nebula> LOOKUP ON shareholder;
+-------------+
| VertexID |
+-------------+
| "player101" |
+-------------+
备注:
如果插入测试数据后才创建索引,请用 REBUILD TAG INDEX <index_name_list>;</index_name_list>
语句重建索引。
7.3 边: edge
7.3.1 创建
语法:
创建Edge type前,需要先用 USE
语句指定工作空间。
CREATE EDGE [IF NOT EXISTS] <edge_type_name>
(
<prop_name> <data_type> [NULL | NOT NULL] [DEFAULT <default_value>] [COMMENT '<comment>']
[{, <prop_name> <data_type> [NULL | NOT NULL] [DEFAULT <default_value>] [COMMENT '<comment>']} ...]
)
[TTL_DURATION = <ttl_duration>]
[TTL_COL = <prop_name>]
[COMMENT = '<comment>'];
</comment></prop_name></ttl_duration></comment></default_value></data_type></prop_name></comment></default_value></data_type></prop_name></edge_type_name>
参数说明 IF NOT EXISTS
检测待创建的Edge type是否存在,只有不存在时,才会创建Edge type。仅检测Edge type的名称,不会检测具体属性。 <edge_type_name></edge_type_name>
每个图空间内的Edge type必须是唯一的。Edge type名称设置后无法修改。Edge type名称由大小写英文字母、数字或下划线组成,区分大写小,且不可使用
关键字和保留字 <prop_name></prop_name>
属性名称。每个Edge type中的属性名称必须唯一。属性的命名规则与Edge type相同。 <data_type></data_type>
以及
日期与时间 NULL \| NOT NULL
指定属性值是否支持为 NULL
。默认值为 NULL
DEFAULT
指定属性的默认值。默认值可以是一个文字值或Nebula Graph支持的表达式。如果插入边时没有指定某个属性的值,则使用默认值。 COMMENT
对单个属性或Edge type的描述。最大为256字节。默认无描述。 TTL_DURATION
指定属性存活时间。超时的属性将会过期。属性值和时间戳差值之和如果小于当前时间戳,属性就会过期。默认值为 0
,表示属性永不过期。 TTL_COL
指定要设置存活时间的属性。属性的数据类型必须是 int
或者 timestamp
。一个Edge type只能指定一个字段为 TTL_COL
。更多TTL的信息请参见
TTL
示例:
nebula> CREATE EDGE IF NOT EXISTS follow(degree int);
创建没有属性的Edge type。
nebula> CREATE EDGE IF NOT EXISTS no_property();
创建包含默认值的Edge type。
nebula> CREATE EDGE IF NOT EXISTS follow_with_default(degree int DEFAULT 20);
对字段p2设置TTL为100秒。
nebula> CREATE EDGE IF NOT EXISTS e1(p1 string, p2 int, p3 timestamp) \
TTL_DURATION = 100, TTL_COL = "p2";
7.3.2 删除
DROP EDGE
语句可以删除当前工作空间内的指定Edge type。
一个边只能有一个Edge type,删除这个Edge type后,用户就 无法访问这个边,下次Compaction操作时会删除该边。
删除Edge type操作仅删除Schema数据,硬盘上的文件或目录不会立刻删除,而是在下一次Compaction操作时删除。
前提条件:
- 登录的用户必须拥有对应权限才能执行
DROP EDGE
语句。详情请参见内置角色权限。 - 确保Edge type不包含任何索引,否则
DROP EDGE
时会报冲突错误[ERROR (-8)]: Conflict!
。删除索引请参见drop index。
语法:
DROP EDGE [IF EXISTS] <edge_type_name>
</edge_type_name>
IF EXISTS
:检测待删除的Edge type是否存在,只有存在时,才会删除Edge type。edge_type_name
:指定要删除的Edge type名称。一次只能删除一个Edge type。
示例:
nebula> CREATE EDGE IF NOT EXISTS e1(p1 string, p2 int);
nebula> DROP EDGE e1;
7.3.3 修改
ALTER EDGE
语句可以修改Edge type的结构。例如增删属性、修改数据类型,也可以为属性设置、修改TTL(Time-To-Live)。
前提条件:
- 确保要修改的属性不包含属性,否则ALTER EDGE 时会报冲突错误
[ERROR (-8)]: Conflict!
。删除索引请参见drop index。
语法:
ALTER EDGE <edge_type_name>
<alter_definition [, alter_definition] ... ] [ttl_definition ttl_definition] [comment="<comment>" ]; alter_definition: | add (prop_name data_type) drop (prop_name) change ttl_definition: ttl_duration="ttl_duration," ttl_col="prop_name" < code></alter_definition></edge_type_name>
edge_type_name
:指定要修改的Edge type名称。一次只能修改一个Edge type。请确保要修改的Edge type在当前工作空间中存在,否则会报错。- 可以在一个
ALTER EDGE
语句中使用多个ADD
、DROP
和CHANGE
子句,子句之间用英文逗号(,)分隔。
示例:
nebula> CREATE EDGE IF NOT EXISTS e1(p1 string, p2 int);
nebula> ALTER EDGE e1 ADD (p3 int, p4 string);
nebula> ALTER EDGE e1 TTL_DURATION = 2, TTL_COL = "p2";
nebula> ALTER EDGE e1 COMMENT = 'edge1';
修改Edge type说明:
尝试使用刚修改的Edge type可能会失败,因为修改是异步实现的。
Nebula Graph将在下一个心跳周期内完成Edge type的修改,为了确保修改成功,可以使用如下方法之一:
- 在
DESCRIBE EDGE
语句的结果中查看Edge type信息,确认修改成功。如果没有修改成功,请等待几秒重试。 - 等待两个心跳周期,例如20秒。
如果需要修改心跳间隔,请为所有配置文件修改参数 heartbeat_interval_secs
。
7.3.4 显示所有edge
语法:
SHOW EDGES;
7.3.5 显示edge的详细
语法:
DESC[RIBE] EDGE <edge_type_name>
</edge_type_name>
DESCRIBE
可以缩写为 DESC
。
7.4 点语句
7.4.1 插入点 INSERT VERTEX
INSERT VERTEX
语句可以在Nebula Graph实例的指定图空间中插入一个或多个点。
语法:
INSERT VERTEX [IF NOT EXISTS] <tag_name> (<prop_name_list>) [, <tag_name> (<prop_name_list>), ...]
{VALUES | VALUE} VID: (<prop_value_list>[, <prop_value_list>])
prop_name_list:
[prop_name [, prop_name] ...]
prop_value_list:
[prop_value [, prop_value] ...]
</prop_value_list></prop_value_list></prop_name_list></tag_name></prop_name_list></tag_name>
IF NOT EXISTS
:用户可以使用IF NOT EXISTS
关键字检测待插入的VID是否存在,只有不存在时,才会插入,如果已经存在,不会进行修改。
Note:
– IF NOT EXISTS
仅检测 VID + Tag 的值是否相同,不会检测属性值。
– IF NOT EXISTS
会先读取一次数据是否存在,因此对性能会有明显影响。
tag_name
:点关联的Tag(点类型)。Tag必须提前创建,详情请参见CREATE TAG。prop_name_list
:需要设置的属性名称列表。VID
:点ID。在Nebula Graph 2.0中支持字符串和整数,需要在创建图空间时设置,详情请参见CREATE SPACE。prop_value_list
:根据prop_name_list
填写属性值。如果属性值和Tag中的数据类型不匹配,会返回错误。如果没有填写属性值,而Tag中对应的属性设置为NOT NULL
,也会返回错误。详情请参见CREATE TAG。INSERT VERTEX
与openCypher中CREATE
的语意不同:INSERT VERTEX
语意更接近于NoSQL(key-value)方式的INSERT语意,或者SQL中的UPSERT
(UPDATE
orINSERT
)。- 相同
VID
和TAG
的情况下,如果没有使用IF NOT EXISTS
,新写入的数据会覆盖旧数据,不存在时会新写入。 - 相同
VID
但不同TAG
的情况下,不同TAG对应的记录不会相互覆盖,不存在会新写入。
示例:
# 插入不包含属性的点
CREATE TAG IF NOT EXISTS t1();
INSERT VERTEX t1() value "10":();
CREATE TAG IF NOT EXISTS t2 (name string,age int);
INSERT VERTEX t2 (name,age) VALUES "11":("n1" , 12)
# 一次插入2个点
INSERT VERTEX t2 (name,age) VALUES "13":( "n3" , 12),"14":("n4" , 16)
一个点可以多次插入属性值,以最后一次为准。
多次插入属性值。
nebula> INSERT VERTEX t2 (name, age) VALUES "11":("n2", 13);
nebula> INSERT VERTEX t2 (name, age) VALUES "11":("n3", 14);
nebula> INSERT VERTEX t2 (name, age) VALUES "11":("n4", 15);
nebula> FETCH PROP ON t2 "11";
+---------------------------------+
| vertices_ |
+---------------------------------+
| ("11" :t2{age: 15, name: "n4"}) |
+---------------------------------+
nebula> CREATE TAG IF NOT EXISTS t5(p1 fixed_string(5) NOT NULL, p2 int, p3 int DEFAULT NULL);
nebula> INSERT VERTEX t5(p1, p2, p3) VALUES "001":("Abe", 2, 3);
插入失败,因为属性p1不能为NULL。
nebula> INSERT VERTEX t5(p1, p2, p3) VALUES "002":(NULL, 4, 5);
[ERROR (-1005)]: Storage Error: The not null field cannot be null.
属性p3为默认值NULL。
nebula> INSERT VERTEX t5(p1, p2) VALUES "003":("cd", 5);
nebula> FETCH PROP ON t5 "003";
+--------------------------------------------+
| vertices_ |
+--------------------------------------------+
| ("003" :t5{p1: "cd", p2: 5, p3: __NULL__}) |
+--------------------------------------------+
属性p1最大长度为5,因此会被截断。
nebula> INSERT VERTEX t5(p1, p2) VALUES "004":("shalalalala", 4);
nebula> FETCH PROP on t5 "004";
+-----------------------------------------------+
| vertices_ |
+-----------------------------------------------+
| ("004" :t5{p1: "shala", p2: 4, p3: __NULL__}) |
+-----------------------------------------------+
使用 IF NOT EXISTS
插入已存在的点时,不会进行修改。
插入点1。
nebula> INSERT VERTEX t2 (name, age) VALUES "1":("n2", 13);
使用IF NOT EXISTS修改点1,因为点1已存在,不会进行修改。
nebula> INSERT VERTEX IF NOT EXISTS t2 (name, age) VALUES "1":("n3", 14);
nebula> FETCH PROP ON t2 "1";
+--------------------------------+
| vertices_ |
+--------------------------------+
| ("1" :t2{age: 13, name: "n2"}) |
+--------------------------------+
7.4.2 删除点 DELETE VERTEX
DELETE VERTEX 语句可以删除点,以及点关联的出边和入边。
DELETE VERTEX 语句一次可以删除一个或者多个点。可以结合管道符一起使用,详情请参见管道符。
note:
DELETE VERTEX
是直接删除点和关联的边。
DELETE TAG
是删除指定点上的指定Tag。当点上只有一个Tag时,执行 DELETE TAG
会删除点,但是不会删除关联的边。
语法:
DELETE VERTEX <vid> [ ,<vid> .... ]
</vid></vid>
示例:
DELETE VERTEX "team1";
# 结合管道符,删除符合条件的点。
nebula> GO FROM "player100" OVER serve WHERE properties(edge).start_year == "2021" YIELD dst(edge) AS id | DELETE VERTEX $-.id;
7.4.3 修改点属性 UPDATE VERTEX
UPDATE VERTEX
语句可以修改点上Tag的属性值。
Nebula Graph支持CAS(compare and set)操作
note : 一次只能修改一个Tag。
语法:
UPDATE VERTEX ON <tag_name> <vid>
SET <update_prop>
[WHEN <condition>]
[YIELD <output>]
</output></condition></update_prop></vid></tag_name>
参数是否必须说明示例 ON <tag_name></tag_name>
是指定点的Tag。要修改的属性必须在这个Tag内。 ON player
<vid></vid>
是指定要修改的点ID。 "player100"
SET <update_prop></update_prop>
是指定如何修改属性值。 SET age = age +1
WHEN <condition></condition>
否指定过滤条件。如果 <condition></condition>
结果为 false
SET
子句不会生效。 WHEN name == "Tim"
YIELD <output></output>
否指定语句的输出格式。 YIELD name AS Name
示例:
// 查看点”player101“的属性。
nebula> FETCH PROP ON player "player101";
+-----------------------------------------------------+
| vertices_ |
+-----------------------------------------------------+
| ("player101" :player{age: 36, name: "Tony Parker"}) |
+-----------------------------------------------------+
// 修改属性age的值,并返回name和新的age。
nebula> UPDATE VERTEX ON player "player101" \
SET age = age + 2 \
WHEN name == "Tony Parker" \
YIELD name AS Name, age AS Age;
+---------------+-----+
| Name | Age |
+---------------+-----+
| "Tony Parker" | 38 |
+---------------+-----+
7.4.4 存在修改,不存在创建 VERTEX
UPSERT VERTEX
语句结合 UPDATE
和 INSERT
,如果点存在,会修改点的属性值;如果点不存在,会插入新的点。
note: UPSERT VERTEX
一次只能修改一个Tag。
UPSERT VERTEX
性能远低于 INSERT
,因为 UPSERT
是一组分片级别的读取、修改、写入操作。
note: 禁止在高并发写操作的情况下使用 UPSERT
语句,请使用 UPDATE
或 INSERT
代替。
语法:
UPSERT VERTEX ON <tag> <vid>
SET <update_prop>
[WHEN <condition>]
[YIELD <output>]
</output></condition></update_prop></vid></tag>
参数是否必须说明示例 ON <tag></tag>
是指定点的Tag。要修改的属性必须在这个Tag内。 ON player
<vid></vid>
是指定要修改或插入的点ID。 "player100"
SET <update_prop></update_prop>
是指定如何修改属性值。 SET age = age +1
WHEN <condition></condition>
否指定过滤条件。 WHEN name == "Tim"
YIELD <output></output>
否指定语句的输出格式。 YIELD name AS Name
插入不存在的点:
如果点不存在,无论 when 子句的条件是否满足,都会插入点,同时执行 set 子句,因此新插入的点的属性值取决于:
SET
子句。- 属性是否有默认值。
示例如下:
// 查看三个点是否存在,结果“Empty set”表示顶点不存在。
nebula> FETCH PROP ON * "player666", "player667", "player668";
+-----------+
| vertices_ |
+-----------+
+-----------+
Empty set
nebula> UPSERT VERTEX ON player "player666" \
SET age = 30 \
WHEN name == "Joe" \
YIELD name AS Name, age AS Age;
+----------+----------+
| Name | Age |
+----------+----------+
| __NULL__ | 30 |
+----------+----------+
nebula> UPSERT VERTEX ON player "player666" \
SET age = 31 \
WHEN name == "Joe" \
YIELD name AS Name, age AS Age;
+----------+-----+
| Name | Age |
+----------+-----+
| __NULL__ | 30 |
+----------+-----+
nebula> UPSERT VERTEX ON player "player667" \
SET age = 31 \
YIELD name AS Name, age AS Age;
+----------+-----+
| Name | Age |
+----------+-----+
| __NULL__ | 31 |
+----------+-----+
nebula> UPSERT VERTEX ON player "player668" \
SET name = "Amber", age = age + 1 \
YIELD name AS Name, age AS Age;
+---------+----------+
| Name | Age |
+---------+----------+
| "Amber" | __NULL__ |
+---------+----------+
上面最后一个示例中,因为 age
没有默认值,插入点时, age
默认值为 NULL
,执行 age = age + 1
后仍为 NULL
。如果 age
有默认值,则 age = age + 1
可以正常执行,例如:
nebula> CREATE TAG IF NOT EXISTS player_with_default(name string, age int DEFAULT 20);
Execution succeeded
nebula> UPSERT VERTEX ON player_with_default "player101" \
SET age = age + 1 \
YIELD name AS Name, age AS Age;
+----------+-----+
| Name | Age |
+----------+-----+
| __NULL__ | 21 |
+----------+-----+
修改存在的点:
如果点存在,且满足 WHEN
子句的条件,就会修改点的属性值。
nebula> FETCH PROP ON player "player101";
+-----------------------------------------------------+
| vertices_ |
+-----------------------------------------------------+
| ("player101" :player{age: 42, name: "Tony Parker"}) |
+-----------------------------------------------------+
nebula> UPSERT VERTEX ON player "player101" \
SET age = age + 2 \
WHEN name == "Tony Parker" \
YIELD name AS Name, age AS Age;
+---------------+-----+
| Name | Age |
+---------------+-----+
| "Tony Parker" | 44 |
+---------------+-----+
如果点存在,但是不满足 WHEN
子句的条件,修改不会生效。
nebula> FETCH PROP ON player "player101";
+-----------------------------------------------------+
| vertices_ |
+-----------------------------------------------------+
| ("player101" :player{age: 44, name: "Tony Parker"}) |
+-----------------------------------------------------+
nebula> UPSERT VERTEX ON player "player101" \
SET age = age + 2 \
WHEN name == "Someone else" \
YIELD name AS Name, age AS Age;
+---------------+-----+
| Name | Age |
+---------------+-----+
| "Tony Parker" | 44 |
+---------------+-----+
7.5 边语句
7.5.1 插入边
INSERT EDGE
语句可以在Nebula Graph实例的指定图空间中插入一条或多条边。边是有方向的,从起始点(src_vid)到目的点(dst_vid)。
INSERT EDGE
的执行方式为覆盖式插入。如果已有Edge type、起点、终点、rank都相同的边,则 覆盖原边。
语法:
INSERT EDGE [IF NOT EXISTS] <edge_type> ( <prop_name_list> ) {VALUES | VALUE}
<src_vid> -> <dst_vid>[@<rank>] : ( <prop_value_list> )
[, <src_vid> -> <dst_vid>[@<rank>] : ( <prop_value_list> ), ...];
<prop_name_list> ::=
[ <prop_name> [, <prop_name> ] ...]
<prop_value_list> ::=
[ <prop_value> [, <prop_value> ] ...]
</prop_value></prop_value></prop_value_list></prop_name></prop_name></prop_name_list></prop_value_list></rank></dst_vid></src_vid></prop_value_list></rank></dst_vid></src_vid></prop_name_list></edge_type>
IF NOT EXISTS
:用户可以使用IF NOT EXISTS
关键字检测待插入的边是否存在,只有不存在时,才会插入。 Note –IF NOT EXISTS
仅检测<edge_type></edge_type>
:边关联的Edge type,只能指定一个Edge type。Edge type必须提前创建,详情请参见CREATE EDGE。<prop_name_list></prop_name_list>
:需要设置的属性名称列表。src_vid
:起始点ID,表示边的起点。dst_vid
:目的点ID,表示边的终点。rank
:可选项。边的rank值。默认值为0
。rank值可以用来区分Edge type、起始点、目的点都相同的边。 openCypher中没有rank的概念。<prop_value_list></prop_value_list>
:根据prop_name_list
填写属性值。如果属性值和Edge type中的数据类型不匹配,会返回错误。如果没有填写属性值,而Edge type中对应的属性设置为NOT NULL
,也会返回错误。详情请参见CREATE EDGE。
示例:
插入不包含属性的边
CREATE EDGE IF NOT EXISTS e1();
INSERT EDGE e1() VALUES "10"->"11":();
插入rank为1的边
INSERT EDGE e1() VALUES "10" -> "11"@1:();
#插入有属性的边
CREATE EDGE IF NOT EXISTS e2 (name string,age int);
INSERT EDGE e2 (name , age ) VALUES "11" -> "13":("n1",1)
#一次性插入2条边
INSERT EDGE e2 (name , age ) VALUES "12"->"13":("n1",1),"13"->"14":("n2",2)
一条边可以多次插入属性值,以最后一次为准。
多次插入属性值。
nebula> INSERT EDGE e2 (name, age) VALUES "11"->"13":("n1", 12);
nebula> INSERT EDGE e2 (name, age) VALUES "11"->"13":("n1", 13);
nebula> INSERT EDGE e2 (name, age) VALUES "11"->"13":("n1", 14);
nebula> FETCH PROP ON e2 "11"->"13";
+-------------------------------------------+
| edges_ |
+-------------------------------------------+
| [:e2 "11"->"13" @0 {age: 14, name: "n1"}] |
+-------------------------------------------+
使用 IF NOT EXISTS
插入已存在的边时,不会进行修改。
插入边。
nebula> INSERT EDGE e2 (name, age) VALUES "14"->"15"@1:("n1", 12);
使用IF NOT EXISTS修改边,因为边已存在,不会进行修改。
nebula> INSERT EDGE IF NOT EXISTS e2 (name, age) VALUES "14"->"15"@1:("n2", 13);
nebula> FETCH PROP ON e2 "14"->"15"@1;
+-------------------------------------------+
| edges_ |
+-------------------------------------------+
| [:e2 "14"->"15" @1 {age: 12, name: "n1"}] |
+-------------------------------------------+
note:
- Nebula Graph 2.6.1 允许存在悬挂边(Dangling edge)。因此可以在起点或者终点存在前,先写边;此时就可以通过
<edgetype>._src</edgetype>
或<edgetype>._dst</edgetype>
获取到(尚未写入的)点VID(不建议这样使用)。 - 目前还不能保证操作的原子性,如果失败请重试,否则会发生部分写入。此时读取该数据的行为是未定义的。
- 并发写入同一条边会报
edge conflict
错误,可稍后重试。 边的INSERT速度
大约是点的INSERT速度一半。原因是INSERT边会对应storaged的两个INSERT,INSERT点
对应storaged的一个INSERT。
7.5.2 删除边
DELETE EDGE
语句可以删除边。一次可以删除一条或多条边。用户可以结合管道符一起使用,详情请参见 管道符。
如果需要删除一个点的所有出边,请删除这个点。详情请参见 DELETE VERTEX。
note:目前还不能保证操作的原子性,如果发生故障请重试。
语法:
DELETE EDGE <edge_type> <src_vid> -> <dst_vid>[@<rank>] [, <src_vid> -> <dst_vid>[@<rank>] ...]
</rank></dst_vid></src_vid></rank></dst_vid></src_vid></edge_type>
示例:
DELETE EDGE serve "player100" -> "team204"@0;
结合管道符,删除符合条件的边。
GO FROM "player100" OVER follow WHEN dst(edge) == "team204" YIELD src(edge) AS src,dst(edge) AS dst,rank(edge) AS rank | DELETE EDGE follow $-.src->$-.dst @ $-.rank;
7.5.3 修改边
UPDATE EDGE
语句可以修改边上 Edge type 的属性。
Nebula Graph 支持 CAS(compare and set)操作。
语法:
UPDATE EDGE ON <edge_type>
<src_vid> -> <dst_vid> [@<rank>]
SET <update_prop>
[WHEN <condition>]
[YIELD <output>]
</output></condition></update_prop></rank></dst_vid></src_vid></edge_type>
参数是否必须说明示例 ON <edge_type></edge_type>
是指定 Edge type。要修改的属性必须在这个 Edge type 内。 ON serve
<src_vid></src_vid>
是指定边的起始点 ID。 "player100"
<dst_vid></dst_vid>
是指定边的目的点 ID。 "team204"
<rank></rank>
否指定边的 rank 值。 10
SET <update_prop></update_prop>
是指定如何修改属性值。 SET start_year = start_year +1
WHEN <condition></condition>
否指定过滤条件。如果 <condition></condition>
结果为 false
SET
子句不会生效。 WHEN end_year < 2010
YIELD <output></output>
否指定语句的输出格式。 YIELD start_year AS Start_Year
示例:
用GO语句查看边的属性值。
GO FROM "player100" OVER serve YIELD propertier(edge).start_year,properties(edge).end_year;
+------------------+----------------+
| serve.start_year | serve.end_year |
+------------------+----------------+
| 1997 | 2016 |
+------------------+----------------+
修改属性 start_year 的值,并返回 end_year 和新的 start_year
UPDATE EDGE ON serve "player100" -> "team204"@0
SET start_year = start_year + 1
WHEN end_yeay > 2010
YIELD start_year,end_year
7.5.4 存在修改,不存在创建 EDGE
UPSERT EDGE
语句结合 UPDATE
和 INSERT
,如果边存在,会更新边的属性;如果边不存在,会插入新的边。
UPSERT EDGE
性能远低于 INSERT
,因为 UPSERT
是一组分片级别的读取、修改、写入操作。
语法:
UPSERT EDGE ON <edge_type>
<src_vid> -> <dst_vid> [@rank]
SET <update_prop>
[WHEN <condition>]
[YIELD <properties>]
</properties></condition></update_prop></dst_vid></src_vid></edge_type>
参数是否必须说明示例 ON <edge_type></edge_type>
是指定 Edge type。要修改的属性必须在这个 Edge type 内。 ON serve
<src_vid></src_vid>
是指定边的起始点 ID。 "player100"
<dst_vid></dst_vid>
是指定边的目的点 ID。 "team204"
<rank></rank>
否指定边的 rank 值。 10
SET <update_prop></update_prop>
是指定如何修改属性值。 SET start_year = start_year +1
WHEN <condition></condition>
否指定过滤条件。 WHEN end_year < 2010
YIELD <output></output>
否指定语句的输出格式。 YIELD start_year AS Start_Year
插入不存在的边
如果边不存在,无论 WHEN
子句的条件是否满足,都会插入边,同时执行 SET
子句,因此新插入的边的属性值取决于:
SET
子句。- 属性是否有默认值。
例如:
- 要插入的边包含基于 Edge type
serve
的属性start_year
和end_year
。 SET
子句指定end_year = 2021
。
不同情况下的属性值如下表。
是否满足 WHEN
子句条件属性是否有默认值 start_year
属性值 end_year
属性值是是默认值 2021
是否 NULL
2021
否是默认值 2021
否否 NULL
2021
示例如下:
查看如下三个点是否有 serve 类型的出边,结果 "Empty set"表示没有 serve 类型的出边
GO FROM "player666","player667","player668"
OVER serve
YIELD properties(edge).start_year,properties(edge).end_year
修改
UPSET EDGE on serve "player666" -> "team200"@0
SET end_year = 2021
WHEN end_year == 2010
YIELD start_year,end_year
UPSERT EDGE on serve \
"player666" -> "team200"@0 \
SET end_year = 2022 \
WHEN end_year == 2010 \
YIELD start_year, end_year;
UPSERT EDGE on serve \
"player668" -> "team200"@0 \
SET start_year = 2000, end_year = end_year + 1 \
YIELD start_year, end_year;
上面最后一个示例中,因为 end_year
没有默认值,插入边时, end_year
默认值为 NULL
,执行 end_year = end_year + 1
后仍为 NULL
。如果 end_year
有默认值,则 end_year = end_year + 1
可以正常执行,例如:
nebula> CREATE EDGE IF NOT EXISTS serve_with_default(start_year int, end_year int DEFAULT 2010);
Execution succeeded
nebula> UPSERT EDGE on serve_with_default \
"player668" -> "team200" \
SET end_year = end_year + 1 \
YIELD start_year, end_year;
修改存在的边:
如果边存在,且满足 WHEN
子句的条件,就会修改边的属性值。
nebula> MATCH (v:player{name:"Ben Simmons"})-[e:serve]-(v2) \
RETURN e;
+-----------------------------------------------------------------------+
| e |
+-----------------------------------------------------------------------+
| [:serve "player149"->"team219" @0 {end_year: 2019, start_year: 2016}] |
+-----------------------------------------------------------------------+
nebula> UPSERT EDGE on serve \
"player149" -> "team219" \
SET end_year = end_year + 1 \
WHEN start_year == 2016 \
YIELD start_year, end_year;
+------------+----------+
| start_year | end_year |
+------------+----------+
| 2016 | 2020 |
+------------+----------+
如果边存在,但是不满足 WHEN
子句的条件,修改不会生效。
nebula> MATCH (v:player{name:"Ben Simmons"})-[e:serve]-(v2) \
RETURN e;
+-----------------------------------------------------------------------+
| e |
+-----------------------------------------------------------------------+
| [:serve "player149"->"team219" @0 {end_year: 2020, start_year: 2016}] |
+-----------------------------------------------------------------------+
nebula> UPSERT EDGE on serve \
"player149" -> "team219" \
SET end_year = end_year + 1 \
WHEN start_year != 2016 \
YIELD start_year, end_year;
+------------+----------+
| start_year | end_year |
+------------+----------+
| 2016 | 2020 |
+------------+----------+
7.6 索引(index)
7.6.1 创建index
索引的概念和使用限制都较为复杂。索引配合 LOOKUP
和 MATCH
语句使用。
CREATE INDEX
语句用于对 Tag、EdgeType 或其属性创建原生索引。通常分别称为”Tag 索引”、”Edge type 索引”和”属性索引”。
- Tag 索引和 Edge type 索引应用于和 Tag、Edge type 自身相关的查询,例如用
LOOKUP
查找有 Tagplayer
的所有点。 - “属性索引”应用于基于属性的查询,例如基于属性
age
找到age == 19
的所有的点。
备注:
- 不要任意在生产环境中使用索引,除非很清楚使用索引对业务的影响。索引会导致写性能下降 90%甚至更多。
- 索引并不用于查询加速。只用于:根据属性定位到点或边,或者统计点边数量。
- 长索引会降低 Storage 服务的扫描性能,以及占用更多内存。建议将索引长度设置为和要被索引的最长字符串相同。索引长度最长为 255,超过部分会被截断。
语法:
CREATE {TAG | EDGE} INDEX [IF NOT EXISTS] <index_name> ON {<tag_name> | <edge_name>} ([<prop_name_list>]) [COMMENT = '<comment>'];
</comment></prop_name_list></edge_name></tag_name></index_name>
参数说明 TAG \| EDGE
指定要创建的索引类型。 IF NOT EXISTS
检测待创建的索引是否存在,只有不存在时,才会创建索引。 <index_name></index_name>
索引名。索引名在一个图空间中必须是唯一的。推荐的命名方式为 i_tagName_propName
。索引名称由大小写英文字母、数字或下划线组成,区分大写小,且不可使用
关键字和保留字 <tag_name> \| <edge_name></edge_name></tag_name>
指定索引关联的 Tag 或 Edge 名称。 <prop_name_list></prop_name_list>
变长
字符串属性创建索引时,必须用 prop_name(length)
指定索引长度;为 Tag 或 Edge type 本身创建索引时,忽略 <prop_name_list></prop_name_list>
COMMENT
索引的描述。最大为 256 字节。默认无描述。
示例:
- 创建 tag 索引
CREATE TAG INDEX player_index on player();
- 创建edge索引
CREATE EDGE INDEX follow_index on follow();
- 创建单属性的索引
CREATE TAG INDEX IF EXISTS player_index_0 on player(name(10));
- 创建复合属性索引
CREATE TAG INDEX IF NOT EXISTS player_index_1 on player(name(10) , age)
备注:
不支持跨 Tag 或者 Edge type创建复合索引
创建索引之后需要重建索引使其生效
7.6.2 显示index
语法:
SHOW {TAG | EDGE} INDEXES;
SHOW INDEXES
语句可以列出当前图空间内的所有 Tag 和 Edge type(包括属性)的索引。
7.6.3 显示创建index语句
语法:
SHOW CREATE {TAG | EDGE} INDEX <index_name>;
</index_name>
SHOW CREATE INDEX
展示创建 Tag 或者 Edge type 时使用的 nGQL 语句,其中包含索引的详细信息,例如其关联的属性。
7.6.4 显示index的信息
语法:
DESCRIBE {TAG | EDGE} INDEX <index_name>;
</index_name>
DESCRIBE INDEX
语句可以查看指定索引的信息,包括索引的属性名称(Field)和数据类型(Type)。
7.6.5 重建index
语法:
REBUILD {TAG | EDGE} INDEX [<index_name_list>];
<index_name_list>::=
[index_name [, index_name] ...]
</index_name_list></index_name_list>
- 可以一次重建多个索引,索引名称之间用英文逗号(,)分隔。如果没有指定索引名称,将会重建所有索引。
- 重建完成后,用户可以使用命令
SHOW {TAG | EDGE} INDEX STATUS
检查索引是否重建完成。详情请参见 SHOW INDEX STATUS。
7.6.6 查询index状态
语法:
SHOW {TAG | EDGE} INDEX STATUS;
索引的状态包括:
QUEUE
:队列中RUNNING
:执行中FINISHED
:已完成FAILED
:失败STOPPED
:停止INVALID
:失效
7.6.7 删除index
语法:
DROP {TAG | EDGE} INDEX [IF EXISTS] <index_name>;
</index_name>
8 查询nGQL
8.1 MATCH
前提条件:
请确保 MATCH
语句有至少一个索引可用,或者其中指定了 VID。如果需要创建索引,但是已经有相关的点、边或属性,用户必须在创建索引后重建索引,索引才能生效。
匹配 Tag
match (n:player) return n
匹配点的属性
match (n:player{name:"Tim"}) return n
或者
match (n:player) where n.name == 'Tim' return n
匹配连接的点
用户可以使用 --
符号表示两个方向的边,并匹配这些边连接的点
MATCH (v:player{name:"Tim Duncan"})--(v2) RETURN v2.name AS Name
8.2 LOOKUP
8.3 GO
语法:
GO [[<m> TO] <n> STEPS ] FROM <vertex_list>
OVER <edge_type_list> [{REVERSELY | BIDIRECT}]
[ WHERE <conditions> ]
[YIELD [DISTINCT] <return_list>]
[{SAMPLE <sample_list> | LIMIT <limit_list>}]
[| GROUP BY {col_name | expr | position} YIELD <col_name>]
[| ORDER BY <expression> [{ASC | DESC}]]
[| LIMIT [<offset>,] <number_rows>];
<vertex_list> ::=
<vid> [, <vid> ...]
<edge_type_list> ::=
edge_type [, edge_type ...]
| *
<return_list> ::=
<col_name> [AS <col_alias>] [, <col_name> [AS <col_alias>] ...]
</col_alias></col_name></col_alias></col_name></return_list></edge_type_list></vid></vid></vertex_list></number_rows></offset></expression></col_name></limit_list></sample_list></return_list></conditions></edge_type_list></vertex_list></n></m>
<n> STEPS</n>
:指定跳数。如果没有指定跳数,默认值 N
为 1
。如果 N
为 0
,Nebula Graph 不会检索任何边。 GO
语句采用的路径类型是 walk
,即遍历时点和边可以重复。
M TO N STEPS
:遍历 M~N
跳的边。如果 M
为 0
,输出结果和 M
为 1
相同,即 GO 0 TO 2
和 GO 1 TO 2
是相同的。 M TO N STEPS
:遍历 M~N
跳的边。如果 M
为 0
,输出结果和 M
为 1
相同,即 GO 0 TO 2
和 GO 1 TO 2
是相同的。
<vertex_list></vertex_list>
:用逗号分隔的点 ID 列表,或特殊的引用符 $-.id
。
<edge_type_list></edge_type_list>
:遍历的 Edge type 列表。
REVERSELY | BIDIRECT
:默认情况下检索的是 <vertex_list></vertex_list>
的出边(正向), REVERSELY
表示反向,即检索入边; BIDIRECT
为双向,即检索正向和反向,通过返回 <edge_type>._type</edge_type>
字段判断方向,其正数为正向,负数为反向。
WHERE <conditions></conditions>
:指定遍历的过滤条件。用户可以在起始点、目的点和边使用 WHERE
子句,还可以结合 AND
、 OR
、 NOT
、 XOR
一起使用。详情参见 WHERE。
YIELD [DISTINCT] <return_list></return_list>
:定义需要返回的输出。 <return_list></return_list>
建议使用 Schea 函数,当前支持 src(edge)
、 dst(edge)
、 type(edge)
、 rank(edge)
、 properties(edge)
、 id(vertex)
、 properties(vertex)
,暂不支持嵌套函数。如果没有指定,默认返回目的点 ID。
SAMPLE <sample_list></sample_list>
:用于在结果集中取样。
LIMIT <limit_list></limit_list>
:用于在遍历过程中逐步限制输出数量。
GROUP BY
:根据指定属性的值将输出分组。分组后需要再次使用 YIELD
定义需要返回的输出。
ORDER BY
:指定输出结果的排序规则。
LIMIT [<offset>,] <number_rows>]</number_rows></offset>
:限制输出结果的行数。
示例:
返回 player102 所属队伍
GO FROM "player102" over serve;
返回距离 player102 两跳的朋友
GO 2 STEPS FROM "player102" OVER follow;
添加过滤条件
GO FROM "player100","player102" over serve \
WHERE serve.start_year > 1995 \
YIELD DISTINCT properties($$).name AS team_name,properties(edge).start_year AS start_year,properties($^).name AS player_name;
遍历多个 Edge type。属性没有值时,会显示 UNKNOWN_PROP
GO FROM "player100" OVER follow ,serve \
YIELD properties(edge).degree,properties(edge).start_year;
返回 player100 入方向的邻居点
GO FROM "player100" OVER follow REVERSELY
YIELD src(edge) AS destination;
该 MATCH 查询与上一个 GO 查询具有相同的语义。
nebula> MATCH (v)<-[e:follow]- (v2) where id(v)="=" 'player100' \ return id(v2) as destination; # 该 match 查询与上一个 go 查询具有相同的语义。 nebula> MATCH (v)<-[e:follow]- (v2) where id(v)="=" 'player100' \ return id(v2) as destination; # 该 match 查询与上一个 go 查询具有相同的语义。 nebula> MATCH (v)<-[e:follow]- (v2)-[e2:serve]->(v3) \
WHERE id(v) == 'player100' \
RETURN v2.name AS FriendOf, v3.name AS Team;
查询 player100 1~2 跳内的朋友。
nebula> GO 1 TO 2 STEPS FROM "player100" OVER follow \
YIELD dst(edge) AS destination;
# 该 MATCH 查询与上一个 GO 查询具有相同的语义。
nebula> MATCH (v) -[e:follow*1..2]->(v2) \
WHERE id(v) == "player100" \
RETURN id(v2) AS destination;
根据年龄分组。
nebula> GO 2 STEPS FROM "player100" OVER follow \
YIELD src(edge) AS src, dst(edge) AS dst, properties($$).age AS age \
| GROUP BY $-.dst \
YIELD $-.dst AS dst, collect_set($-.src) AS src, collect($-.age) AS age;
分组并限制输出结果的行数。
nebula> $a = GO FROM "player100" OVER follow YIELD src(edge) AS src, dst(edge) AS dst; \
GO 2 STEPS FROM $a.dst OVER follow \
YIELD $a.src AS src, $a.dst, src(edge), dst(edge) \
| ORDER BY $-.src | OFFSET 1 LIMIT 2;
在多个边上通过 IS NOT EMPTY 进行判断。
nebula> GO FROM "player100" OVER follow WHERE $$.player.name IS NOT EMPTY YIELD dst(edge);
</-[e:follow]-></-[e:follow]-></-[e:follow]->
8.4 FETCH
参考官网
8.5 UNWIN
参考官网
8.6 SHOW
参考官网
Original: https://blog.csdn.net/fan_bigdata/article/details/122363652
Author: fan_bigdata
Title: 图数据库nebula graph小结
原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/555090/
转载文章受原作者版权保护。转载请注明原作者出处!