Nebula nGQL常用语法

wylc123 10月前 ⋅ 266 阅读

一、注册 Storage 服务

1.1 添加 Storage 主机。

执行如下命令添加主机:

ADD HOSTS <ip>:<port> [,<ip>:<port> ...];

示例:

nebula> ADD HOSTS 192.168.10.100:9779, 192.168.10.101:9779, 192.168.10.102:9779;
1.2 检查主机状态,确认全部在线。

SHOW HOSTS;

1.3 删除 Storage 主机
DROP HOSTS <ip>:<port> [,<ip>:<port> ...];
DROP HOSTS "<hostname>":<port> [,"<hostname>":<port> ...];

、图空间语句

2.1. 创建图空间
CREATE SPACE demo_test(
 partition_num=20, #指定图空间的分片数量。建议设置为集群中硬盘数量的 20 倍(HDD 硬盘建议为 2 倍)。例如集群中有 3 个硬盘,建议设置 60 个分片。默认值为 100。
 replica_factor=1, #分片副本数量,建议在生产环境中设置为 3,在测试环境中设置为 1。副本数量必须是奇数。默认值为 1
 vid_type=FIXED_STRING(32) #必选参数。指定点 ID 的数据类型。可选值为FIXED_STRING(<N>)和INT64
)
COMMENT='测试图空间' #图空间注解
2.2. 克隆图空间
CREATE SPACE <new_graph_space_name> AS <old_graph_space_name>;
例如:
CREATE SPACE clone_demo_space AS demo_test
2.3.切换到一个图空间
USE clone_demo_space

三、创建 Tag 和 Edge type

nGQL 语法
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>'];

参数详情请参见 CREATE TAG 和 CREATE EDGE

示例

创建 Tag:playerteam,以及 Edge type:followserve。说明如下表。

名称 类型 属性
player Tag name (string), age (int)
team Tag name (string)
follow Edge type degree (int)
serve Edge type start_year (int), end_year (int)
nebula> CREATE TAG player(name string, age int);

nebula> CREATE TAG team(name string);

nebula> CREATE EDGE follow(degree int);

nebula> CREATE EDGE serve(start_year int, end_year int);

四、 插入数据

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

nGQL 语法
  • 插入点
    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] ...]  
    

    vid是 Vertex ID 的缩写,vid在一个图空间中是唯一的。参数详情请参见 INSERT VERTEX

  • 插入边
    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> ] ...]
    

    参数详情请参见 INSERT EDGE

示例
  • 插入代表球员和球队的点。
    nebula> INSERT VERTEX player(name, age) VALUES "player100":("Tim Duncan", 42);
    
    nebula> INSERT VERTEX player(name, age) VALUES "player101":("Tony Parker", 36);
    
    nebula> INSERT VERTEX player(name, age) VALUES "player102":("LaMarcus Aldridge", 33);
    # 一次插入 2 个点。 nebula> INSERT VERTEX team(name) VALUES "team203":("Trail Blazers"), "team204":("Spurs");

    # 一次插入两个 Tag 的属性到同一个点。
    insert vertex person(name,age),card(id,phone) values "player0105":("宋彬",33,"370522199002181416","18612100611");
  • 插入代表球员和球队之间关系的边。
    nebula> INSERT EDGE follow(degree) VALUES "player101" -> "player100":(95);
    
    nebula> INSERT EDGE follow(degree) VALUES "player101" -> "player102":(90);
    
    nebula> INSERT EDGE follow(degree) VALUES "player102" -> "player100":(75);
    
    nebula> INSERT EDGE serve(start_year, end_year) VALUES "player101" -> "team204":(1999, 2018),"player102" -> "team203":(2006,  2015);
    

五、查询数据

  • GO 语句可以根据指定的条件遍历数据库。GO语句从一个或多个点开始,沿着一条或多条边遍历,返回YIELD子句中指定的信息。
  • FETCH 语句可以获得点或边的属性。
  • LOOKUP 语句是基于索引的,和WHERE子句一起使用,查找符合特定条件的数据。
  • MATCH 语句是查询图数据最常用的,可以灵活的描述各种图模式,但是它依赖索引去匹配 NebulaGraph 中的数据模型,性能也还需要调优。
nGQL 语法
  • GO
    GO [[<M> TO] <N> {STEP|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>];
    
  • FETCH
    • 查询 Tag 属性

      FETCH PROP ON {<tag_name>[, tag_name ...] | *}
      <vid> [, vid ...]
      YIELD <return_list> [AS <alias>];
      
    • 查询边属性

      FETCH PROP ON <edge_type> <src_vid> -> <dst_vid>[@<rank>] [, <src_vid> -> <dst_vid> ...]
      YIELD <output>;
      
  • LOOKUP
    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>] ...]; 
  • MATCH
    MATCH <pattern> [<clause_1>]  RETURN <output>  [<clause_2>];
    
示例
GO语句示例
  • 从 VID 为player101的球员开始,沿着边follow找到连接的球员。
    nebula> GO FROM "player101" OVER follow YIELD id($$);
    +-------------+
    | id($$)      |
    +-------------+
    | "player100" |
    | "player102" |
    +-------------+
    
  • 从 VID 为player101的球员开始,沿着边follow查找年龄大于或等于 35 岁的球员,并返回他们的姓名和年龄,同时重命名对应的列。
    nebula> GO FROM "player101" OVER follow WHERE properties($$).age >= 35 \
            YIELD properties($$).name AS Teammate, properties($$).age AS Age;
    +-----------------+-----+
    | Teammate        | Age |
    +-----------------+-----+
    | "Tim Duncan"    | 42  |
    +-----------------+-----+
    
    子句/符号 说明
    YIELD 指定该查询需要返回的值或结果。
    $$ 表示边的终点。
    \ 表示换行继续输入。
  • 从 VID 为player101的球员开始,沿着边follow查找连接的球员,然后检索这些球员的球队。为了合并这两个查询请求,可以使用管道符或临时变量。

    • 使用管道符

      nebula> GO FROM "player101" OVER follow YIELD dst(edge) AS id | \
              GO FROM $-.id OVER serve YIELD properties($$).name AS Team, \
              properties($^).name AS Player;
      +-----------------+---------------------+
      | Team            | Player              |
      +-----------------+---------------------+
      | "Trail Blazers" | "LaMarcus Aldridge" |
      +-----------------+---------------------+
      
      子句/符号 说明
      $^ 表示边的起点。
      | 组合多个查询的管道符,将前一个查询的结果集用于后一个查询。
      $- 表示管道符前面的查询输出的结果集。
    • 使用临时变量

      Note

      当复合语句作为一个整体提交给服务器时,其中的临时变量会在语句结束时被释放。

      nebula> $var = GO FROM "player101" OVER follow YIELD dst(edge) AS id; \
              GO FROM $var.id OVER serve YIELD properties($$).name AS Team, \
              properties($^).name AS Player;
      +-----------------+---------------------+
      | Team            | Player              |
      +-----------------+---------------------+
      | "Trail Blazers" | "LaMarcus Aldridge" |
      +-----------------+---------------------+
      
FETCH语句示例

查询 VID 为player100的球员的属性。

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

Note

LOOKUPMATCH的示例

在下文的索引 部分查看。

六、其他操作

6.1 修改点和边

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

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

Note

每个 partition 内部,UPSERT 操作是一个串行操作,所以执行速度比执行 INSERT 或 UPDATE 慢很多。其仅在多个 partition 之间有并发。

nGQL 语法
  • UPDATE
    UPDATE VERTEX <vid> SET <properties to be updated>
    [WHEN <condition>] [YIELD <columns>];
    
  • UPDATE
    UPDATE EDGE ON <edge_type> <source vid> -> <destination vid> [@rank] 
    SET <properties to be updated> [WHEN <condition>] [YIELD <columns to be output>];
    
  • UPSERT点或边
    UPSERT {VERTEX <vid> | EDGE <edge_type>} SET <update_columns>
    [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修改某条边的degree属性,然后用FETCH检查结果。
    nebula> UPDATE EDGE ON follow "player101" -> "player100" SET degree = 96;
    
    nebula> FETCH PROP ON follow "player101" -> "player100" YIELD properties(edge);
    +------------------+
    | properties(EDGE) |
    +------------------+
    | {degree: 96}     |
    +------------------+
    
  • 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  |
    +---------+-----+
    
6.2 删除点和边
nGQL 语法
  • 删除点
    DELETE VERTEX <vid1>[, <vid2>...]
    
  • 删除边
    DELETE EDGE <edge_type> <src_vid> -> <dst_vid>[@<rank>]
    [, <src_vid> -> <dst_vid>...]
    
示例
  • 删除点
    nebula> DELETE VERTEX "player111", "team203";
    
  • 删除边
    nebula> DELETE EDGE follow "player101" -> "team204";
    
6.3 使用索引

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

使用索引必读

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

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

nGQL 语法
  • 创建索引
    CREATE {TAG | EDGE} INDEX [IF NOT EXISTS] <index_name>
    ON {<tag_name> | <edge_name>} ([<prop_name_list>]) [COMMENT = '<comment>'];
    
  • 重建索引
    REBUILD {TAG | EDGE} INDEX <index_name>;
    

Note

为没有指定长度的变量属性创建索引时,需要指定索引长度。在 utf-8 编码中,一个中文字符占 3 字节,请根据变量属性长度设置合适的索引长度。例如 10 个中文字符,索引长度需要为 30。详情请参见创建索引

基于索引的LOOKUPMATCH示例

确保LOOKUPMATCH有一个索引可用。如果没有,请先创建索引。

找到 Tag 为player的点的信息,它的name属性值为Tony Parker

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

相关文章推荐

全部评论: 0

    我有话说: