跳转至
开发版采用单机部署,无需产品 License 文件。需要多机部署或大规模性能测试? 了解企业版

表变量

表变量以表格形式存储数据。在悦数图数据库开发版中,表变量主要用于保存查询结果、遍历中间结果,以及驱动批量插入、更新或删除点和边。

本文介绍悦数图数据库开发版中使用的本地表变量。

语法

table_variable_definition
BINDING TABLE table_variable :: TYPED BINDING TABLE { field_name value_type , } = table_value_constructor { field_name , } = table_value_constructor = table_value_constructor
table_value_constructor
table_expression { procedure_body }
table_expression
{ field_name : value_expression , } , ( value_expression , ) ,

table_variable_definition ::=
    'BINDING'? 'TABLE' table_variable ( 
        ((( '::' | 'TYPED' ) 'BINDING TABLE')?  
            '{' (field_name value_type) (',' (field_name value_type))* '}' ('=' table_value_constructor)?
        )  
        | '{' field_name (',' field_name)* '}' '=' table_value_constructor
        | '=' table_value_constructor
    ) 

table_value_constructor ::=
    table_expression
    | '{' procedure_body '}' 

table_expression ::=
    ( '{' (field_name ':' value_expression) (',' (field_name ':' value_expression))* '}' ) (',' ( '{' (field_name ':' value_expression) (',' (field_name ':' value_expression))* '}' ) )* 
    | ( '(' value_expression (',' value_expression)* ')' ) ( ',' ( '(' value_expression (',' value_expression)* ')' ) )*            

参数

table_variable

要定义的表变量的名称。table_variable可以是常规标识符或使用反引号(`)包围的分隔标识符。有关标识符的更多信息,请参见标识符命名规则。

field_name

表中字段的名称。field_name必须是一个标识符。有关标识符的更多信息,请参见标识符命名规则。

value_type

字段所持有的值的数据类型。支持的数据类型包括数值、字符串、布尔值、时间和日期、向量、列表、集合、映射、记录。更多信息,请参见数据类型。

value_expression

表中字段的值。value_expression必须是一个不依赖于任何变量的表达式。有关值表达式的更多信息,请参见值表达式。

procedure_body

一个或者一组被执行的 DQL 语句。更多信息,请参见过程体和 DQL 语句。

成员函数

clear()

清除表变量中的所有数据。

函数签名

clear() -> VOID

使用说明

只能使用SET语句来调用clear()函数。更多信息,请参见 SET。

示例

以下示例基于示例数据集。

定义表变量时不赋值

'''
TABLE t :: TABLE { a INT, 
                   b BOOL, 
                   c TYPED STRING, 
                   d DOUBLE, 
                   e LIST<DECIMAL(10, 4)>, 
                   f RECORD {x INT, y STRING}, 
                   g DATE, 
                   h VECTOR<3,FLOAT> 
   }  
   FINISH
'''

定义表变量时声明字段类型

'''
TABLE t TYPED TABLE { id INT64, name STRING, birthDate DATE } =  
    { id: 10001, name: 'Alice', birthDate: DATE '1990-01-01' },  
    { id: 10002, name: 'Bob', birthDate: DATE '1991-02-02' },  
    { id: 10003, name: 'Charlie', birthDate: DATE '1992-03-03' }  
FOR re IN t  
RETURN  re.id, re.name, re.birthDate 
'''

上述语句定义了表变量t,并显式声明了表中字段id、name和birthDate的数据类型,同时向表中添加了三行数据。之后,FOR子句遍历表变量t,并返回字段id、name和birthDate的值。

返回:

+-------+---------+--------------+
| re.id | re.name | re.birthDate |
+-------+---------+--------------+
| 10001 | Alice   | 1990-01-01   |
| 10002 | Bob     | 1991-02-02   |
| 10003 | Charlie | 1992-03-03   |
+-------+---------+--------------+

定义表变量时不声明字段类型

'''
TABLE t { id, name, birthDate } =  
    ( 10001, 'Alice', DATE '1990-01-01' ),  
    ( 10002, 'Bob', DATE '1991-02-02' ),  
    ( 10003, 'Charlie', DATE '1992-03-03' )  
FOR re IN t  
RETURN  re.id, re.name, re.birthDate
'''

上述语句定义了表变量t,未声明其字段id、name和birthDate的数据类型,但在向表中添加数据时指定了各个字段的数据类型。之后,FOR子句遍历表变量t,并返回字段id、name和birthDate的值。

返回:

+-------+---------+--------------+
| re.id | re.name | re.birthDate |
+-------+---------+--------------+
| 10001 | Alice   | 1990-01-01   |
| 10002 | Bob     | 1991-02-02   |
| 10003 | Charlie | 1992-03-03   |
+-------+---------+--------------+

从查询结果定义表变量

从查询推断字段名称和类型

'''
TABLE t = { USE movie 
            MATCH (v:Person) 
            RETURN v.name AS name, v.id AS id 
            ORDER BY name 
            LIMIT 3 
          } 
FOR rec IN t                                
RETURN rec.name, rec.id
'''

返回:

+------------------+--------+
| rec.name         | rec.id |
+------------------+--------+
| Aaron Eckhart    | 6383   |
| Ada Lonati       | 162562 |
| Adam Alexi-Malle | 20804  |
+------------------+--------+

上述语句通过MATCH语句的查询结果定义了表变量t。字段名称(name、id)及其类型从RETURN子句的别名中自动推断。

显式指定字段名称

'''
TABLE t { personName, personId } = {
    USE movie
    MATCH (v:Person)
    RETURN v.name, v.id
    ORDER BY v.name
    LIMIT 3
}
FOR rec IN t
RETURN rec.personName, rec.personId
'''

返回:

+------------------+--------------+
| rec.personName   | rec.personId |
+------------------+--------------+
| Aaron Eckhart    | 6383         |
| Ada Lonati       | 162562       |
| Adam Alexi-Malle | 20804        |
+------------------+--------------+

上述语句定义了表变量t,并显式指定字段名称为personName和personId。查询返回的v.name和v.id按顺序映射到指定的字段名称。

显式指定字段名称和类型

'''
TABLE t TYPED TABLE { name STRING, id INT64 } = {
    USE movie
    MATCH (v:Person)
    RETURN v.name, v.id 
    ORDER BY v.name
    LIMIT 3
}
FOR rec IN t
RETURN rec.name, rec.id
'''

返回:

+------------------+--------+
| rec.name         | rec.id |
+------------------+--------+
| Aaron Eckhart    | 6383   |
| Ada Lonati       | 162562 |
| Adam Alexi-Malle | 20804  |
+------------------+--------+

上述语句定义了表变量t,并指定了类型。查询输出必须与声明的类型兼容,否则会报错。

在查询中使用关联变量

'''
VALUE personId = 100
TABLE friends = {
    USE movie
    MATCH (f:Person)-[:Act]->(m:Movie)
    WHERE f.id = personId
    RETURN f.id AS fid, f.name AS fname
}
FOR rec IN friends
RETURN rec.fid, rec.fname
'''

返回:

+---------+----------------+
| rec.fid | rec.fname      |
+---------+----------------+
| 100     | Scott Speedman |
+---------+----------------+

上述语句首先定义了值变量personId,然后定义了表变量friends,其查询在WHERE子句中引用了personId。这样可以使用预先定义的变量进行参数化查询。

清除表变量

'''
TABLE t {id, name} = (10, "new1"), (20, "new2")
SET t.clear()
FOR rec IN t
RETURN rec.id, rec.name
'''

返回:

+--------+----------+
| rec.id | rec.name |
+--------+----------+
+--------+----------+

使用表变量批量插入点

'''
TABLE t { id, name, birthDate } =  
    ( 10001, 'Alice', DATE '1990-01-01' ),  
    ( 10002, 'Bob', DATE '1991-02-02' ),  
    ( 10003, 'Charlie', DATE '1992-03-03' )  
USE movie 
FOR re IN t 
INSERT (@Actor {id: re.id, name: re.name, birthDate: re.birthDate})
'''

上述语句定义了表变量t,并遍历表变量的字段,插入点类型为Actor的点到图movie中。

关于插入操作的更多信息,请参见 INSERT。

使用表变量批量插入点和边

'''
TABLE t { actor_id, movie_id, movie_name } =  
    ( 10001 , 20001, 'Movie1' ),  
    ( 10002 , 20002, 'Movie2' ),  
    ( 10003 , 20003, 'Movie3' )  
USE movie 
FOR re IN t 
MATCH (a@Actor) WHERE a.id = re.actor_id 
INSERT (a)-[@Act]->(@Movie {id: re.movie_id, name: re.movie_name})
'''

上述语句定义了表变量t,并遍历表变量将数据插入到图movie中。该语句基于表变量的字段actor_id匹配点类型为Actor的点,并基于字段movie_id和movie_name的值插入点类型为Movie的点,并在这些点之间插入边。

使用表变量批量更新点

'''
TABLE t { id, new_name } =  
    ( 10001, 'Alice_renamed' ),  
    ( 10002, 'Bob_renamed' ),  
    ( 10003, 'Charlie_renamed' )  
USE movie 
FOR re IN t 
MATCH (a@Actor) WHERE a.id = re.id 
SET a.name = re.new_name
'''

上述语句定义了表变量t,并基于表变量的字段id匹配点类型为Actor的点。然后,根据表变量的字段new_name更新匹配到的点的属性name。

关于更新操作的更多信息,请参见 SET。

使用表变量批量删除点

'''
TABLE t { id } =  
    ( 10001 ),  
    ( 10002 ),  
    ( 10003 )  
USE movie 
FOR re IN t 
MATCH (a@Actor) WHERE a.id = re.id 
DETACH DELETE a
'''

上述语句定义了表变量t,并基于表变量的字段id匹配点类型为Actor的点。然后,删除匹配到的点及与其连接的所有边。

关于删除操作的更多信息,请参见 DELETE。

在临时图中使用表变量

以下示例基于 CREATE TEMPORARY GRAPH 中创建的临时图#movie_temporary_graph。

'''
USE #movie_temporary_graph {
    TABLE result_table TYPED TABLE { id INT, name STRING } 

    MATCH (a@Movie)
    PER NODE (a) {
        EXPORT a.id AS id, a.name AS name INTO result_table
    }

    FOR r IN result_table
    RETURN r.id AS id, r.name AS name
    LIMIT 3
}
'''

返回:

+-----+------------+
| id  | name       |
+-----+------------+
| 572 | Next Door  |
| 427 | My Uncle   |
| 269 | Breathless |
+-----+------------+

上述语句在已有的临时图#movie_temporary_graph中定义表变量result_table。该表变量通过匹配计算语句查询图中的Movie点,并将点的id和name字段导出到result_table中。最后,使用FOR子句遍历result_table并返回3条记录。