Nebula Graph-04-NebulaGraph nGQL的介绍和使用

nGQL介绍

系列文章:
Nebula Graph-01-Nebula Graph简介和安装以及客户端连接
Nebula Graph-02-NebulaGraph高阶配置、用户管理、日志
Nebula Graph-03-NebulaGraph Studio-可视化web工具安装和使用
Nebula Graph-04-NebulaGraph nGQL的介绍和使用
Nebula Graph-05-NebulaGraph nGQL和SQL区别
Nebula Graph-06-NebulaGraph Java 使用 和SpringBoot集成Nebula Graph


官网说明:https://docs.nebula-graph.com.cn/3.6.0/3.ngql-guide/1.nGQL-overview/1.overview/

1:什么是 nGQL

nGQL是 NebulaGraph 使用的的声明式图查询语言,支持灵活高效的图模式,而且 nGQL 是为开发和运维人员设计的类 SQL 查询语言,易于学习。

整体看下来,nGQL给我的感觉虽然是Nebula Graph 自己研发的语言,但是综合了mysql等关系数据库语言和java等高级编程语言整合而来的。内容太多,需要用心学习。

2:nGQL 可以做什么

  • 支持图遍历
  • 支持模式匹配
  • 支持聚合
  • 支持修改图
  • 支持访问控制
  • 支持聚合查询
  • 支持索引
  • 支持大部分 openCypher 9 图查询语法(不支持修改和控制语法)

nGQL 概念

1:nGQL 语法符号的说明

符号含义
< >语法元素的名称。
:定义元素的公式。
[ ]可选元素。
{ }显式的指定元素。
可以重复多次。

nGQL 注释

  • nebula> RETURN 1+1; # 这条注释延续到行尾。
  • nebula> RETURN 1+1; // 这条注释延续到行尾。
  • nebula> RETURN 1 /* 这是一条行内注释 */ + 1 == 2;
  • nebula> RETURN 11 +
    /* 多行注释
    用反斜线来换行。
    */ 12;

nGQL 语句中的反斜线(\)代表换行。
如果 nGQL 语句以#或者//开头,不会执行该行命令并且会返回提示StatementEmpty。

2:大小写区分

1:标识符区分大小写
以下语句会出现错误,因为my_space和MY_SPACE是两个不同的图空间。

nebula> CREATE SPACE IF NOT EXISTS my_space (vid_type=FIXED_STRING(30));
nebula> use MY_SPACE;
[ERROR (-1005)]: SpaceNotFound:

2:关键字不区分大小写
以下语句是等价的,因为show和spaces是关键字。

nebula> show spaces;
nebula> SHOW SPACES;
nebula> SHOW spaces;
nebula> show SPACES;

3:函数不区分大小写
函数名称不区分大小写,例如count()、COUNT()、couNT()是等价的。

nebula> WITH [NULL, 1, 1, 2, 2] As a \
        UNWIND a AS b \
        RETURN count(b), COUNT(*), couNT(DISTINCT b);
+----------+----------+-------------------+
| count(b) | COUNT(*) | couNT(distinct b) |
+----------+----------+-------------------+
| 4        | 5        | 2                 |
+----------+----------+-------------------+

3:关键字

关键字是 nGQL 中具有特殊含义的词,例如CREATE TAG语句中的CREATE和TAG。需要经过特殊处理才能作为标识符使用的关键字被称为保留关键字,而能够直接作为标识符使用的这部分关键字被称为非保留关键字。

不建议在创建 Schema 时使用关键字。如果必须使用关键字,请注意一下规则:

  • 使用保留关键字或特殊字符作为标识符时,必须用反引号()包围,例如 AND`。否则,会返回语义错误,创建失败。
  • 使用非保留关键字作为标识符时:
    若其包含大写字母,必须用反引号(`)包围,例如 `Comment`。否则,虽然能创建成功,系统会自动将标识符转化为全小写字母,也即 `comment`。
    若其为全小写字母,可以不使用反引号(`)包围。

保留关键字:

ACROSS
ADD
ALTER
AND
AS
ASC
ASCENDING
BALANCE
BOOL
BY
CASE
CHANGE
COMPACT
CREATE
DATE
DATETIME
DELETE
DESC
DESCENDING
DESCRIBE
DISTINCT
DOUBLE
DOWNLOAD
DROP
DURATION
EDGE
EDGES
EXISTS
EXPLAIN
FALSE
FETCH
FIND
FIXED_STRING
FLOAT
FLUSH
FROM
GEOGRAPHY
GET
GO
GRANT
IF
IGNORE_EXISTED_INDEX
IN
INDEX
INDEXES
INGEST
INSERT
INT
INT16
INT32
INT64
INT8
INTERSECT
IS
JOIN
LEFT
LIST
LOOKUP
MAP
MATCH
MINUS
NO
NOT
NULL
OF
ON
OR
ORDER
OVER
OVERWRITE
PATH
PROP
REBUILD
RECOVER
REMOVE
RESTART
RETURN
REVERSELY
REVOKE
SET
SHOW
STEP
STEPS
STOP
STRING
SUBMIT
TAG
TAGS
TIME
TIMESTAMP
TO
TRUE
UNION
UNWIND
UPDATE
UPSERT
UPTO
USE
VERTEX
VERTICES
WHEN
WHERE
WITH
XOR
YIELD

非保留关键字

ACCOUNT
ADMIN
AGENT
ALL
ALLSHORTESTPATHS
ANALYZER
ANY
ATOMIC_EDGE
AUTO
BASIC
BIDIRECT
BOTH
CHARSET
CLEAR
CLIENTS
COLLATE
COLLATION
COMMENT
CONFIGS
CONTAINS
DATA
DBA
DEFAULT
DIVIDE
DRAINER
DRAINERS
ELASTICSEARCH
ELSE
END
ENDS
ES_QUERY
FORCE
FORMAT
FULLTEXT
GOD
GRANTS
GRAPH
GROUP
GROUPS
GUEST
HDFS
HOST
HOSTS
HTTP
HTTPS
INTO
IP
JOB
JOBS
KILL
LEADER
LIMIT
LINESTRING
LISTENER
LOCAL
MERGE
META
NEW
NOLOOP
NONE
OFFSET
OPTIONAL
OUT
PART
PARTITION_NUM
PARTS
PASSWORD
PLAN
POINT
POLYGON
PROFILE
QUERIES
QUERY
READ
REDUCE
RENAME
REPLICA_FACTOR
RESET
ROLE
ROLES
S2_MAX_CELLS
S2_MAX_LEVEL
SAMPLE
SEARCH
SERVICE
SESSION
SESSIONS
SHORTEST
SHORTESTPATH
SIGN
SINGLE
SKIP
SNAPSHOT
SNAPSHOTS
SPACE
SPACES
STARTS
STATS
STATUS
STORAGE
SUBGRAPH
SYNC
TEXT
TEXT_SEARCH
THEN
TOP
TTL_COL
TTL_DURATION
USER
USERS
UUID
VALUE
VALUES
VARIABLES
VID_TYPE
WHITELIST
WRITE
ZONE
ZONES

4:数据类型

数值

nGQL 支持整数和浮点数。

  • 整数¶
    nGQL 支持带符号的 64 位整数(INT64)、32 位整数(INT32)、16 位整数(INT16)和 8 位整数(INT8)。
    在这里插入图片描述
  • 浮点数¶
    nGQL 支持单精度浮点(FLOAT)和双精度浮点(DOUBLE)。
    在这里插入图片描述

布尔

NebulaGraph 使用关键字BOOL声明布尔数据类型,可选值为true或false。

nGQL 支持以如下方式使用布尔值:

  • 将属性值的数据类型定义为布尔。
  • 在WHERE子句中用布尔值作为判断条件。

字符串

NebulaGraph 支持定长字符串和变长字符串。

nGQL 中的字符串声明方式如下:

  • 使用关键字STRING声明变长字符串。
  • 使用关键字FIXED_STRING()声明定长字符串,为字符串长度,例如FIXED_STRING(32)。

字符串的表示方式为用双引号或单引号包裹,例如"Hello, Cooper"或’Hello, Cooper’。

日期和时间类型

本文介绍日期和时间的类型,包括DATE、TIME、DATETIME、TIMESTAMP和DURATION

  • DATE¶
    DATE包含日期,但是不包含时间。 NebulaGraph 检索和显示DATE的格式为YYYY-MM-DD。支持的范围是-32768-01-01到32767-12-31。
    date()支持的属性名称包括year、month和day。date()支持输入YYYY、YYYY-MM或YYYY-MM-DD,未输入的月份或日期默认为01。

  • TIME¶
    TIME包含时间,但是不包含日期。 NebulaGraph 检索和显示TIME的格式为hh:mm:ss.msmsmsususus。支持的范围是00:00:00.000000到23:59:59.999999。
    time()支持的属性名称包括hour、minute和second。

  • DATETIME¶
    DATETIME包含日期和时间。 NebulaGraph 检索和显示DATETIME的格式为YYYY-MM-DDThh:mm:ss.msmsmsususus。支持的范围是-32768-01-01T00:00:00.000000到32767-12-31T23:59:59.999999。

datetime()支持的属性名称包括year、month、day、hour、minute和second。
datetime()可将TIMESTAMP类型的日期值转换成DATETIME类型的日期值。TIMESTAMP类型的日期值取值范围:0~9223372036。
datetime()支持int类型的参数,该int参数表示时间戳。

  • TIMESTAMP¶
    TIMESTAMP包含日期和时间。支持的范围是 UTC 时间的1970-01-01T00:00:01到2262-04-11T23:47:16。以时间戳形式存储和显示

  • DURATION¶
    DURATION是一段连续的时间,由years、months、days、hours、minutes、seconds六个Key自由组合成的Map类型数据表示。例如duration({years: 12, months: 5, days: 14, hours: 16, minutes: 12, seconds: 70})。

NULL

默认情况下,插入点或边时,属性值可以为NULL,用户也可以设置属性值不允许为NULL(NOT NULL),即插入点或边时必须设置该属性的值,除非创建属性时已经设置默认值。

在这里插入图片描述

列表—list

列表(List)是复合数据类型,一个列表是一组元素的序列,可以通过元素在序列中的位置访问列表中的元素。

列表用左方括号([)和右方括号(])包裹多个元素,各个元素之间用英文逗号(,)隔开。元素前后的空格在列表中被忽略,因此可以使用换行符、制表符和空格调整格式。

[1,2,3]

集合—set

集合(Set)是复合数据类型,集合中是一组元素,与列表(List)不同的是,集合中的元素是无序的,且不允许重复。

集合用左花括号({)和右花括号(})包裹多个元素,各个元素之间用英文逗号(,)隔开。元素前后的空格在集合中被忽略,因此可以使用换行符、制表符和空格调整格式。

{1,2,3}

映射—map

映射(Map)是复合数据类型。一个映射是一组键值对(Key-Value)的无序集合。在映射中,Key 是字符串类型,Value 可以是任何数据类型。用户可以通过map[‘’]的方法获取映射中的元素。

映射用左花括号({)和右花括号(})包裹多个键值对,各个键值对之间用英文逗号(,)隔开。键值对前后的空格在映射中被忽略,因此可以使用换行符、制表符和空格调整格式。

{key1: ‘Value1’, Key2: ‘Value2’}

类型转换¶

类型转换是指将表达式的类型转换为另一个类型。

NebulaGraph 支持显式地转换类型。

  • toBoolean()¶
    toBoolean() 将字符串转换为布尔。

  • toFloat()¶
    toFloat() 将整数或字符串转换为浮点数。

  • toString()¶
    toString() 将任意非复合数据类型数据转换为字符串类型。

  • toInteger()¶
    toInteger() 将浮点或字符串转换为整数。

  • toSet()¶
    toSet() 将列表或集合转换为集合。

  • hash()¶
    hash() 返回参数的哈希值。其参数可以是数字、字符串、列表、布尔值、NULL 等类型的值,或者计算结果为这些类型的表达式。

5:运算符

比较符

在这里插入图片描述

布尔符

在这里插入图片描述

管道符

nGQL 支持使用管道符(|)将多个查询组合起来。

  • 在 SQL 中,子查询是嵌套在查询语句中的。
  • 在 nGQL 中,子查询是通过类似 shell 中的管道符(|)实现的。

集合运算符—set

1:UNION、UNION DISTINCT、UNION ALL—并集

  • 运算符UNION DISTINCT(或使用缩写UNION)返回两个集合 A 和 B 的并集,不包含重复的元素。
  • 运算符UNION ALL返回两个集合 A 和 B 的并集,包含重复的元素。

2:INTERSECT—交集

  • 运算符INTERSECT返回两个集合 A 和 B 的交集

3:MINUS—差集

  • 运算符MINUS返回两个集合 A 和 B 的差异,即A-B。请注意left和right的顺序,A-B表示在集合 A 中,但是不在集合 B 中的元素。

字符串运算符

在这里插入图片描述

列表运算符¶

NebulaGraph 支持使用列表(List)运算符进行运算。支持的运算符如下。
在这里插入图片描述

算术运算符

在这里插入图片描述

运算符优先级

nGQL 运算符的优先级从高到低排列如下(同一行的运算符优先级相同):

  • -(负数)
  • !、NOT
  • *、/、%
  • -、+
  • ==、>=、>、<=、<、<>、!=
  • AND
  • OR、XOR
  • =(赋值)

如果表达式中有相同优先级的运算符,运算是从左到右进行,只有赋值操作是例外(从右到左运算)。

运算符的优先级决定运算的顺序,要显式修改运算顺序,可以使用圆括号。

nGQL 的具体使用

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:对 Tag 或其属性创建原生索引
  • CREATE EDGE INDEX:对 EdgeType 或其属性创建原生索引

默认心跳周期是 10 秒。修改心跳周期参数heartbeat_interval_secs

2:使用下图的数据集演示基础操作的语法

在这里插入图片描述

3:创建和选择图空间

创建图空间—CREATE SPACE

CREATE SPACE [IF NOT EXISTS] <graph_space_name> (
[partition_num = <partition_number>,]
[replica_factor = <replica_number>,]
vid_type = {FIXED_STRING(<N>) | INT64}
)

[COMMENT = '<comment>'];

参数说明
IF NOT EXISTS检测待创建的图空间是否存在,只有不存在时,才会创建图空间。仅检测图空间的名称,不会检测具体属性。
<graph_space_name>在 NebulaGraph 实例中唯一标识一个图空间。图空间名称以英文字母开头,支持 1~4 字节的 UTF-8 编码字符,包括英文字母(区分大小写)、数字、中文等,但是不包括除下划线外的特殊字符。使用特殊字符或保留关键字时,需要用反引号(`)包围,详情参见关键字和保留字。
partition_num指定图空间的分片数量。建议设置为集群中硬盘数量的 20 倍(HDD 硬盘建议为 2 倍)。例如集群中有 3 个硬盘,建议设置 60 个分片。默认值为 100。
replica_factor指定每个分片的副本数量。建议在生产环境中设置为 3,在测试环境中设置为 1。由于需要基于多数表决,副本数量必须是奇数。默认值为 1。
vid_type必选参数。指定点 ID 的数据类型。可选值为FIXED_STRING()和INT64。INT等同于INT64。FIXED_STRING()表示数据类型为定长字符串,长度为N字节,超出长度会报错。例如,UTF-8中,一个中文字符的长度为三个字节,如果设置N为 12,那么vid_type为最多 4 个中文字符。INT64表示数据类型为整数。
COMMENT图空间的描述。最大为 256 字节。默认无描述。

示例:

nebula> CREATE SPACE basketballplayer(partition_num=15, replica_factor=1, vid_type=fixed_string(30));

选择图空间— USE test

USE <graph_space_name>;

示例:

nebula[(root)]> USE basketballplayer;

查看创建的图空间

nebula> SHOW SPACES;
+--------------------+
| Name               |
+--------------------+
| "basketballplayer" |
+--------------------+

4:创建 Tag 和 Edge type

nGQL 语法(创建 Tag 和 Edge type语法一样)

CREATE {TAG | EDGE} [IF NOT EXISTS] {<tag_name> | <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>'];

参数说明:

参数说明
IF NOT EXISTS检测待创建的 Tag 是否存在,只有不存在时,才会创建 Tag。仅检测 Tag 的名称,不会检测具体属性。
<tag_name> 或<edge_type_name>1、每个图空间内的 Tag 必须是唯一的。
2、Tag 名称设置后无法修改。
3、Tag 名称以英文字母开头,支持 1~4 字节的 UTF-8 编码字符,包括英文字母(区分大小写)、数字、中文等,但是不包括除下划线外的特殊字符。使用特殊字符或保留关键字时,需要用反引号(`)包围且不能使用英文句号(.),详情参见关键字和保留字。
<prop_name>属性名称。每个 Tag 中的属性名称必须唯一。属性的命名规则与 Tag 相同。
<data_type>属性的数据类型,目前支持数值、布尔、字符串以及日期与时间。
NULL | NOT NULL指定属性值是否支持为NULL。默认值为NULL。
DEFAULT指定属性的默认值。默认值可以是一个文字值或 NebulaGraph 支持的表达式。如果插入点时没有指定某个属性的值,则使用默认值。
COMMENT对单个属性或 Tag 的描述。最大为 256 字节。默认无描述。
TTL_DURATION指定时间戳差值,单位:秒。时间戳差值必须为 64 位非负整数。属性值和时间戳差值之和如果小于当前时间戳,属性就会过期。默认值为0,表示属性永不过期。
TTL_COL指定要设置存活时间的属性。属性的数据类型必须是int或者timestamp。一个 Tag 只能指定一个字段为TTL_COL。更多 TTL 的信息请参见 TTL。

创建 Tag 示例—CREATE TAG

# 创建包含默认值的 Tag。
nebula> CREATE TAG IF NOT EXISTS player_with_default(name string, age int DEFAULT 20);

创建 Edge type示例—CREATE EDGE

# 创建包含默认值的 Edge type。
nebula> CREATE EDGE IF NOT EXISTS follow_with_default(degree int DEFAULT 20);

5:插入点和边

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

插入点—INSERT VERTEX

INSERT VERTEX [IF NOT EXISTS] [tag_props, [tag_props] ...]
VALUES VID: ([prop_value_list])

tag_props:
  tag_name ([prop_name_list])

prop_name_list:
   [prop_name [, prop_name] ...]

prop_value_list:
   [prop_value [, prop_value] ...]   

参数说明
IF NOT EXISTS:检测待插入的 VID 是否存在,只有不存在时,才会插入,如果已经存在,不会进行修改。
IF NOT EXISTS 仅检测 VID + Tag 的值是否相同,不会检测属性值。
IF NOT EXISTS 会先读取一次数据是否存在,因此对性能会有明显影响。
tag_name:点关联的 Tag(点类型)。Tag 的创建,详情请参见 CREATE TAG。
property_name:需要设置的属性名称。
vid:点 ID。在 NebulaGraph 3.2.0 中支持字符串和整数,需要在创建图空间时设置
property_value:根据prop_name_list填写属性值。如果没有填写属性值,而 Tag 中对应的属性设置为NOT NULL,会返回错误。

示例代码:

nebula> CREATE TAG IF NOT EXISTS t2 (name string, age int);                
nebula> INSERT VERTEX t2 (name, age) VALUES "11":("n1", 12);

# 一次插入 2 个点。
nebula> INSERT VERTEX t2 (name, age) VALUES "13":("n3", 12), "14":("n4", 8); 
nebula> CREATE TAG IF NOT EXISTS t3(p1 int);
nebula> CREATE TAG IF NOT EXISTS t4(p2 string);

# 一次插入两个 Tag 的属性到同一个点。
nebula> INSERT VERTEX  t3 (p1), t4(p2) VALUES "21": (321, "hello");

插入边—INSERT EDGE

  • INSERT EDGE语句可以在 NebulaGraph 实例的指定图空间中插入一条或多条边。边是有方向的,从起始点(src_vid)到目的点(dst_vid)。

  • INSERT EDGE的执行方式为覆盖式插入。如果已有 Edge type、起点、终点、rank 都相同的边,则覆盖原边。

语法:

INSERT EDGE [IF NOT EXISTS] <edge_type> ( <prop_name_list> ) VALUES 
<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> ] ...]

参数说明
IF NOT EXISTS用户可以使用IF NOT EXISTS关键字检测待插入的边是否存在,只有不存在时,才会插入。 IF NOT EXISTS 仅检测<边的类型、起始点、目的点和 rank>是否存在,不会检测属性值是否重合。 IF NOT EXISTS 会先读取一次数据是否存在,因此对性能会有明显影响。
<edge_type>边关联的 Edge type,只能指定一个 Edge type。Edge type 必须提前创建
<prop_name_list>需要设置的属性名称列表。
src_vid起始点 ID,表示边的起点。
dst_vid目的点 ID,表示边的终点。
rank可选项。边的 rank 值。默认值为0。
<prop_value_list>根据prop_name_list填写属性值。如果属性值和 Edge type 中的数据类型不匹配,会返回错误。如果没有填写属性值,而 Edge type 中对应的属性设置为NOT NULL

示例代码:

nebula> CREATE EDGE IF NOT EXISTS e2 (name string, age int); 
nebula> INSERT EDGE e2 (name, age) VALUES "11"->"13":("n1", 1);

# 一次插入 2 条边。
nebula> INSERT EDGE e2 (name, age) VALUES \
        "12"->"13":("n1", 1), "13"->"14":("n2", 2); 

6:查询数据

GO 语句—从一个点开始便利边

GO 语句可以根据指定的条件遍历数据库。GO语句从一个或多个点开始,沿着一条或多条边遍历,返回YIELD子句中指定的信息。
GO从给定起始点开始遍历图。GO语句采用的路径类型是walk,即遍历时点和边都可以重复。

官网说明:https://docs.nebula-graph.com.cn/3.2.0/3.ngql-guide/7.general-query-statements/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_by_list_clause> }]
[| GROUP BY {<col_name> | expression> | <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>] ...]

参数说明
STEPS指定跳数。如果没有指定跳数,默认值N为1。如果N为0,NebulaGraph 不会检索任何边。
M TO N STEPS遍历M~N跳的边。如果M为0,输出结果和M为1相同,即GO 0 TO 2和GO 1 TO 2是相同的
<vertex_list>用逗号分隔的点 ID 列表,或特殊的引用符$-.id。
<edge_type_list>遍历的 Edge type 列表。
REVERSELY / BIDIRECT默认情况下检索的是<vertex_list>的出边(正向),REVERSELY表示反向,即检索入边;BIDIRECT 为双向,即检索正向和反向,通过返回 <edge_type>._type 字段判断方向,其正数为正向,负数为反向。
WHERE 指定遍历的过滤条件。用户可以在起始点、目的点和边使用WHERE子句,还可以结合AND、OR、NOT、XOR一起使用
YIELD [DISTINCT] <return_list>定义需要返回的输出。<return_list>建议使用 Schema 函数,当前支持src(edge)、dst(edge)、type(edge)等,暂不支持嵌套函数
SAMPLE <sample_list>用于在结果集中取样
<limit_by_list_clause>用于在遍历过程中逐步限制输出数量。
GROUP BY根据指定属性的值将输出分组。分组后需要再次使用YIELD定义需要返回的输出。
ORDER BY指定输出结果的排序规则。
LIMIT [,] <number_rows>]限制输出结果的行数。

在这里插入图片描述

  • 示例代码
# 返回 player102 所属队伍。
nebula> GO FROM "player102" OVER serve YIELD dst(edge);
+-----------+
| dst(EDGE) |
+-----------+
| "team203" |
| "team204" |
+-----------+
# 返回距离 player102 两跳的朋友。
nebula> GO 2 STEPS FROM "player102" OVER follow YIELD dst(edge);
+-------------+
| dst(EDGE)   |
+-------------+
| "player101" |
| "player125" |
| "player100" |
| "player102" |
| "player125" |
+-------------+

# 添加过滤条件。
nebula> GO FROM "player100", "player102" OVER serve \
        WHERE properties(edge).start_year > 1995 \
        YIELD DISTINCT properties($$).name AS team_name, properties(edge).start_year AS start_year, properties($^).name AS player_name;

+-----------------+------------+---------------------+
| team_name       | start_year | player_name         |
+-----------------+------------+---------------------+
| "Spurs"         | 1997       | "Tim Duncan"        |
| "Trail Blazers" | 2006       | "LaMarcus Aldridge" |
| "Spurs"         | 2015       | "LaMarcus Aldridge" |
+-----------------+------------+---------------------+

FETCH 语句—FETCH 语句可以获得点或边的属性。

FETCH可以获取指定点或边的属性值。
官网说明:https://docs.nebula-graph.com.cn/3.2.0/3.ngql-guide/7.general-query-statements/4.fetch/
在这里插入图片描述

获取点的属性值

语法:

FETCH PROP ON {<tag_name>[, tag_name ...] | *}
<vid> [, vid ...]
YIELD <return_list> [AS <alias>];
参数说明
tag_nameTag 名称。
*表示当前图空间中的所有 Tag。
vid点 ID。
YIELD定义需要返回的输出。详情请参见 YIELD。
AS设置别名。

示例:基于 Tag 获取点的属性值

nebula> FETCH PROP ON player "player100" YIELD properties(vertex);
+-------------------------------+
| properties(VERTEX)            |
+-------------------------------+
| {age: 42, name: "Tim Duncan"} |
+-------------------------------+

示例:获取点的指定属性值

nebula> FETCH PROP ON player "player100" \
        YIELD properties(vertex).name AS name;
+--------------+
| name         |
+--------------+
| "Tim Duncan" |
+--------------+
获取边的属性值

语法:

FETCH PROP ON <edge_type> <src_vid> -> <dst_vid>[@<rank>] [, <src_vid> -> <dst_vid> ...]
YIELD <output>;
参数说明
edge_typeEdge type 名称。
src_vid起始点 ID,表示边的起点。
dst_vid目的点 ID,表示边的终点。
rank边的 rank。可选参数,默认值为0。起始点、目的点、Edge type 和 rank 可以唯一确定一条边。
YIELD定义需要返回的输出。详情请参见 YIELD。

示例:获取边的所有属性值

# 获取连接 player100 和 team204 的边 serve 的所有属性值。
nebula> FETCH PROP ON serve "player100" -> "team204" YIELD properties(edge);
+------------------------------------+
| properties(EDGE)                   |
+------------------------------------+
| {end_year: 2016, start_year: 1997} |
+------------------------------------+

示例:获取边的指定属性值

nebula> FETCH PROP ON serve "player100" -> "team204"    \
        YIELD properties(edge).start_year;
+-----------------------------+
| properties(EDGE).start_year |
+-----------------------------+
| 1997                        |
+-----------------------------+

LOOKUP 语句—LOOKUP 语句是基于索引的,和WHERE子句一起使用,查找符合特定条件的数据。

官网说明:https://docs.nebula-graph.com.cn/3.2.0/3.ngql-guide/7.general-query-statements/5.lookup/

LOOKUP根据索引遍历数据。用户可以使用LOOKUP实现如下功能:

  • 根据WHERE子句搜索特定数据。
  • 通过 Tag 列出点:检索指定 Tag 的所有点 ID。
  • 通过 Edge type 列出边:检索指定 Edge type 的所有边的起始点、目的点和 rank。
  • 统计包含指定 Tag 的点或属于指定 Edge type 的边的数量。

语法:

LOOKUP ON {<vertex_tag> | <edge_type>}
[WHERE <expression> [AND <expression> ...]]
YIELD <return_list> [AS <alias>];

<return_list>
    <prop_name> [AS <col_alias>] [, <prop_name> [AS <prop_alias>] ...];
参数说明
WHERE 指定遍历的过滤条件,还可以结合布尔运算符 AND 和 OR 一起使用。
YIELD定义需要返回的输出。
AS设置别名

在这里插入图片描述

示例:检索点
返回 Tag 为player且name为Tony Parker的点。

nebula> LOOKUP ON player \
        WHERE player.name == "Tony Parker" \
        YIELD properties(vertex).name AS name, properties(vertex).age AS age;
+---------------+-----+
| name          | age |
+---------------+-----+
| "Tony Parker" | 36  |
+---------------+-----+

示例:检索边
返回 Edge type 为follow且degree为90的边。

nebula> LOOKUP ON follow \
        WHERE follow.degree == 90 YIELD edge AS e;
+----------------------------------------------------+
| e                                                  |
+----------------------------------------------------+
| [:follow "player109"->"player125" @0 {degree: 90}] |
| [:follow "player118"->"player120" @0 {degree: 90}] |
| [:follow "player118"->"player131" @0 {degree: 90}] |
...

示例:

// 为 name 属性创建索引 player_index_1。
nebula> CREATE TAG INDEX IF NOT EXISTS player_index_1 ON player(name(20));

// 重建索引确保能对已存在数据生效。
nebula> REBUILD TAG INDEX player_index_1
+------------+
| New Job Id |
+------------+
| 31         |
+------------+

// 使用 LOOKUP 语句检索点的属性。
nebula> LOOKUP ON player WHERE player.name == "Tony Parker" \
        YIELD properties(vertex).name AS name, properties(vertex).age AS age;
+---------------+-----+
| name          | age |
+---------------+-----+
| "Tony Parker" | 36  |
+---------------+-----+

MATCH 语句—MATCH语句提供基于模式(pattern)匹配的搜索功能

MATCH 语句是查询图数据最常用的,可以灵活的描述各种图模式,但是它依赖索引去匹配 NebulaGraph 中的数据模型,性能也还需要调优。

官网说明:https://docs.nebula-graph.com.cn/3.2.0/3.ngql-guide/7.general-query-statements/2.match/

语法:
与GO或LOOKUP等其他查询语句相比,MATCH的语法更灵活。MATCH语句采用的路径类型是trail,即遍历时只有点可以重复,边不可以重复。

MATCH <pattern> [<clause_1>]  RETURN <output>  [<clause_2>];
参数说明
patternMATCH语句支持匹配一个或多个模式,多个模式之间用英文逗号(,)分隔。例如(a)-[]->(b),©-[]->(d)。
clause_1支持WHERE、WITH、UNWIND、OPTIONAL MATCH子句,也可以使用MATCH作为子句。
output定义需要返回的输出。可以使用AS设置输出的别名。
clause_2支持ORDER BY、LIMIT子句。

注意事项
除以下三种情况之外,请确保 MATCH 语句有至少一个索引可用。

  • MATCH语句中WHERE子句使用 id() 函数指定了点的 VID,不需要创建索引即可执行。
  • 当遍历所有点边时,例如MATCH (v) RETURN v LIMIT N,不需要创建索引,但必须使用LIMIT限制输出结果数量。
  • 当遍历指定 Tag 的点或指定 Edge Type 的边时,例如MATCH (v:player) RETURN v LIMIT N,不需要创建索引,但必须使用LIMIT限制输出结果数量。

示例:

// 为 name 属性创建索引 player_index_1。
nebula> CREATE TAG INDEX IF NOT EXISTS player_index_1 ON player(name(20));

// 重建索引确保能对已存在数据生效。
nebula> REBUILD TAG INDEX player_index_1
+------------+
| New Job Id |
+------------+
| 31         |
+------------+

// 使用 MATCH 语句检索点的属性。
nebula> MATCH (v:player{name:"Tony Parker"}) RETURN v;
+-----------------------------------------------------+
| v                                                   |
+-----------------------------------------------------+
| ("player101" :player{age: 36, name: "Tony Parker"}) |
+-----------------------------------------------------+

FIND PATH—查找指定起始点和目的点之间的路径

用户可在配置文件nebula-graphd.conf中添加num_operator_threads参数提高FIND PATH的查询性能。num_operator_threads的取值为2~10,该值不能超过 Graph 服务所在机器的 CPU 核心个数,建议设置为 Graph 服务所在机器的 CPU 核心个数。

语法:

FIND { SHORTEST | ALL | NOLOOP } PATH [WITH PROP] FROM <vertex_id_list> TO <vertex_id_list>
OVER <edge_type_list> [REVERSELY | BIDIRECT] 
[<WHERE clause>] [UPTO <N> {STEP|STEPS}] 
YIELD path as <alias>
[| ORDER BY $-.path] [| LIMIT <M>];

<vertex_id_list> ::=
    [vertex_id [, vertex_id] ...]
参数说明
SHORTEST查找所有最短路径。
ALL查找所有路径。
NOLOOP查找非循环路径。
WITH PROP展示点和边的属性。不添加本参数则隐藏属性。
<vertex_id_list>点 ID 列表。多个点用英文逗号(,)分隔。支持 − 和 -和 var。
<edge_type_list>Edge type 列表。多个 Edge type 用英文逗号(,)分隔。*表示所有 Edge type。
REVERSELY 、 BIDIRECTREVERSELY表示反向,BIDIRECT表示双向。
<WHERE clause>可以使用WHERE子句过滤边属性。
UPTO <N> {STEP|STEPS}路径的最大跳数。默认值为5。
ORDER BY $-.path将返回结果进行排序。排序规则参见 Path。
LIMIT 指定返回的最大行数。
  • FIND PATH语句检索的路径类型为trail,即检索的路径只有点可以重复,边不可以重复。
  • 指定起始点和目的点的列表后,会返回起始点和目的点所有组合的路径。
  • 搜索所有路径时可能会出现循环。
  • 使用WHERE子句时只能过滤边属性,暂不支持过滤点属性,且不支持函数。
  • graphd 是单进程查询,会占用很多内存。

在这里插入图片描述

示例:

# 查找并返回 player102 到 team204 的最短路径。
nebula> FIND SHORTEST PATH FROM "player102" TO "team204" OVER * YIELD path AS p;
+--------------------------------------------+
| p                                          |
+--------------------------------------------+
| <("player102")-[:serve@0 {}]->("team204")> |
+--------------------------------------------+
# 查找所有从 player100 到 team204,并且 degree 为空或者大于等于 0 的路径。
nebula> FIND ALL PATH FROM "player100" TO "team204" OVER * WHERE follow.degree is EMPTY or follow.degree >=0 YIELD path AS p;
+------------------------------------------------------------------------------+
| p                                                                            |
+------------------------------------------------------------------------------+
| <("player100")-[:serve@0 {}]->("team204")>                                   |
| <("player100")-[:follow@0 {}]->("player125")-[:serve@0 {}]->("team204")>     |
| <("player100")-[:follow@0 {}]->("player101")-[:serve@0 {}]->("team204")>     |
| ...                                                                          |
+------------------------------------------------------------------------------+

GET SUBGRAPH—单点子图

  • 我们只给定一个起点和拓展部署,用 GET SUBGRAPH 可以帮我们获取同样的 BFS 出去的子图
  • GET SUBGRAPH语句查询并返回一个通过从指定点出发对图进行游走而生成的子图。在GET SUBGRAPH语句中,用户可以指定游走的步数以及游走所经过的边的类型或方向。

语法:

GET SUBGRAPH [WITH PROP] [<step_count> {STEP|STEPS}] FROM {<vid>, <vid>...}
[{IN | OUT | BOTH} <edge_type>, <edge_type>...]
[WHERE <expression> [AND <expression> ...]]
YIELD [VERTICES AS <vertex_alias>] [, EDGES AS <edge_alias>];
参数说明
WITH PROP展示属性。不添加本参数则隐藏属性。
step_count指定从起始点开始的跳数,返回从 0 到step_count跳的子图。必须是非负整数。默认值为 1。
vid指定起始点 ID。
edge_type指定 Edge type。可以用IN、OUT和BOTH来指定起始点上该 Edge type 的方向。默认为BOTH。
WHERE指定遍历的过滤条件,可以结合布尔运算符 AND 使用。
YIELD定义需要返回的输出。可以仅返回点或边。必须设置别名。
  • GET SUBGRAPH语句检索的路径类型为trail,即检索的路径只有点可以重复,边不可以重复。

在这里插入图片描述

示例:查询从点player101开始、0~1 跳、所有 Edge type 的子图

nebula> GET SUBGRAPH 1 STEPS FROM "player101" YIELD VERTICES AS nodes, EDGES AS relationships;
+-------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------+
| nodes                                                                   | relationships                                                                                                               |
+-------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------+
| [("player101" :player{})]                                               | [[:serve "player101"->"team204" @0 {}], [:follow "player101"->"player100" @0 {}], [:follow "player101"->"player102" @0 {}]] |
| [("team204" :team{}), ("player100" :player{}), ("player102" :player{})] | [[:follow "player102"->"player100" @0 {}]]                                                                                  |
+-------------------------------------------------------------------------+-----------------------------------------------------------------------------------------------------------------------------+

示例:查询从点player101开始、0~1 跳、follow类型的入边的子图。

nebula> GET SUBGRAPH 1 STEPS FROM "player101" IN follow YIELD VERTICES AS nodes, EDGES AS relationships;
+---------------------------+---------------+
| nodes                     | relationships |
+---------------------------+---------------+
| [("player101" :player{})] | []            |
+---------------------------+---------------+

7:修改点和边

  • 用户可以使用UPDATE语句或UPSERT语句修改现有数据。

  • UPSERT是UPDATE和INSERT的结合体。当使用UPSERT更新一个点或边,如果它不存在,数据库会自动插入一个新的点或边。

UPDATE 点

语法:

UPDATE VERTEX <vid> SET <properties to be updated>
[WHEN <condition>] [YIELD <columns>];

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

nebula> UPDATE VERTEX "player100" SET player.name = "Tim";

nebula> FETCH PROP ON player "player100" YIELD properties(vertex);
+------------------------+
| properties(VERTEX)     |
+------------------------+
| {age: 42, name: "Tim"} |
+------------------------+

UPDATE 边

UPDATE EDGE <source vid> -> <destination vid> [@rank] OF <edge_type>
SET <properties to be updated> [WHEN <condition>] [YIELD <columns to be output>];

示例:用UPDATE修改某条边的degree属性,然后用FETCH检查结果。

nebula> UPDATE EDGE "player101" -> "player100" OF follow SET degree = 96;

nebula> FETCH PROP ON follow "player101" -> "player100" YIELD properties(edge);
+------------------+
| properties(EDGE) |
+------------------+
| {degree: 96}     |
+------------------+

UPSERT点或边

UPSERT {VERTEX <vid> | EDGE <edge_type>} SET <update_columns>
[WHEN <condition>] [YIELD <columns>];

示例:用INSERT插入一个 VID 为player111的点,然后用UPSERT更新它。

nebula> INSERT VERTEX player(name,age) VALUES "player111":("David West", 38);

nebula> 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;
+---------+-----+
| Name    | Age |
+---------+-----+
| "David" | 49  |
+---------+-----+

8:删除点和边

删除点

DELETE VERTEX <vid1>[, <vid2>...]

示例:删除点

nebula> DELETE VERTEX "player111", "team203";

删除边

DELETE EDGE <edge_type> <src_vid> -> <dst_vid>[@<rank>]
[, <src_vid> -> <dst_vid>...]

示例:删除边

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

9:索引

  • 用户可以通过 CREATE INDEX 语句为 Tag 和 Edge type 增加索引。

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

  • 必须为“已写入但未构建索引”的数据重建索引,否则无法在MATCH和LOOKUP语句中返回这些数据。

创建索引

CREATE {TAG | EDGE} INDEX [IF NOT EXISTS] <index_name>
ON {<tag_name> | <edge_name>} ([<prop_name_list>]) [COMMENT = '<comment>'];

示例:

// 为 name 属性创建索引 player_index_1。
nebula> CREATE TAG INDEX IF NOT EXISTS player_index_1 ON player(name(20));

重建索引

REBUILD {TAG | EDGE} INDEX <index_name>;

示例:

// 重建索引确保能对已存在数据生效。
nebula> REBUILD TAG INDEX player_index_1
+------------+
| New Job Id |
+------------+
| 31         |
+------------+

10:nGQL 命令汇总

这里是官网的nGQL命令汇总,包含各种函数、查询语句、调优的方法。

官网说明:https://docs.nebula-graph.com.cn/3.6.0/2.quick-start/6.cheatsheet-for-ngql-command/#_1

总结nGQL

nGQL 语句类型

我们先强调一下概念:nGQL 是 NebulaGraph Graph Query Language 的缩写,它表示 NebulaGraph 的查询语言,而 nGQL 的语句可以不严谨地分为这几部分:

  • NebulaGraph 独有 DQL 查询语句(Data Query Language)
  • NebulaGraph OpenCypher DQL
  • NebulaGraph DML 写语句(Data Mutation Language)
  • NebulaGraph DDL Schema 语句(Data Definition Language)
  • NebulaGraph Admin Queries 管理语句

NebulaGraph 独有 DQL

用一句话描述来说,nGQL 的独有 DQL 一共分成四类语句:

图拓展:GO

在这里插入图片描述

索引反查:LOOKUP

在这里插入图片描述

取属性:FETCH PROP

在这里插入图片描述

路径与子图:FIND PATH 与 GET SUBGRAPH

在这里插入图片描述

几个特别的元素 【管道:|】和【引用属性: $ 开头】

  • 管道:|
  • 引用属性: $ 开头的几个符号,用来描述一些特定的上下文
    NebulaGraph 的管道设计和 Unix-Shell 的设计很像,可以将简单的几种语句结合起来,有强大的表达力。
    在这里插入图片描述

nGQL速查表: 一次了解所有 nGQL 的用法。

在这里插入图片描述

各查询中路径分别是那种类型

  • GO从给定起始点开始遍历图。GO语句采用的路径类型是walk,即遍历时点和边都可以重复。
  • MATCH语句采用的路径类型是trail,即遍历时只有点可以重复,边不可以重复。
  • FIND PATH语句检索的路径类型为trail,即检索的路径只有点可以重复,边不可以重复。
  • GET SUBGRAPH语句检索的路径类型为trail,即检索的路径只有点可以重复,边不可以重复。

了解查询的原理和优化

https://www.siwei.io/ngql-execution-plan/

  • 21
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

苍煜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值