创建、安装、执行查询

GSQL查询是一种经过编译后的数据检索和计算任务。 用户可以通过编写查询来探索任何他们喜欢的数据图形。整个过程分三步:读取并计算图数据,更新图形以及输出结果。 GSQL查询非常类似于用户自定义过程或函数:它可以有一个或多个输入参数。同时GSQL查询可以通过两种方式输出:要么返回一个值,要么将结果打印出来。整个查询过程分三步:

  1. 创建查询:定义查询的功能

  2. 安装查询:编译查询

  3. 运行查询:输入参数并执行查询

查询操作的权限

只有查询编写者(querywriter)或更高级别身份的用户(如架构师(architect),管理员(admin)和超级用户(superuser))可以进行创建,安装和删除查询。

而对于某个给定的图形,只有查询编写者或更高身份的用户才可以在该图形上执行查询操作。

如何对哪些用户组可以执行哪些查询进行更精确地控制:

1.将查询分组,并关联到对应的的权限组中。

2.把图形和每个权限组挂钩。 如果您愿意,这些图形拥有相同的域。

3.创建查询,将每个查询分配给适当的权限组。

创建查询的EBNF范式
createQuery := CREATE [OR REPLACE] QUERY name "(" [parameterList] ")" FOR GRAPH name
              [RETURNS "("  baseType | accumType ")"]
              [API "(" stringLiteral ")"]
              "{" [typedefs][declStmts][declExceptStmts] queryBodyStmts "}"
 
parameterValueList := parameterValue [, parameterValue]*
parameterValue := parameterConstant
               | "[" parameterValue [, parameterValue]* "]"  // BAG or SET
               | "(" stringLiteral, stringLiteral ")"        // a generic VERTEX value
parameterConstant := numeric | stringLiteral | TRUE | FALSE
parameterList := parameterType name ["=" constant]["," parameterType name ["=" constant]]*
 
typedefs := (typedef ";")+
declStmts := (declStmt ";")+
declStmt := baseDeclStat | accumDeclStmt | fileDeclStmt
declExceptStmts := (declExceptStmt ";")+
queryBodyStmts := (queryBodyStmt ";")+
 
installQuery := INSTALL QUERY [installOptions] ( "*" | ALL |name [, name]* )
runQuery := RUN QUERY [runOptions] name "(" parameterValueList ")"
 
showQuery := SHOW QUERY name
dropQuery := DROP QUERY ( "*" | ALL | name [, name]* )

创建查询的语法格式

createQuery := CREATE [OR REPLACE] QUERY name "(" [parameterList] ")" FOR GRAPH name
              [RETURNS "("  baseType | accumType ")"]
              "{" [typedefs][declStmts][declExceptStmts] queryBodyStmts "}"

创建查询(CREATE QUERY)是指在一个给定的图形数据库Schema上定义的所需要的查询功能。

一个查询包含其名称,参数列表,要查询的图的名称,返回值的类型(可选)(详见“返回结果的语法”一节),输出api的说明符(可选),以及查询的正文主体。正文主体又由一个typedef序列(可选),一个声明序列(可选)以及一个或多个语句组成。查询的具体动作由正文定义。

DISTRIBUTED选项仅适用于已跨群集分布图的安装。 如果指定,查询将使用不同的执行模型运行,这可以为遍历集群的大部分的查询提供更好的性能。 并非所有GSQL查询语言功能都在DISTRIBUTED模式下受支持。 有关详细信息,请参阅单独的文档:分布式查询模式。

OR REPLACE is deprecated

如果包含可选关键字OR REPLACE,则该查询将覆盖之前旧的同名的查询。除非新的查询中有错误,则老的查询还会保留。如果未使用OR REPLACE选项,则GSQL将拒绝执行与现有查询重名的CREATE QUERY指令。

Typedef允许程序员在查询内使用自定义类。该声明支持累加器(详见“累加器”一章)和全局/局部变量。所有累加器和全局变量都必须在使用前声明。正文中可以使用各种类型的语句。通常,一个查询的核心语句是一个或多个SELECT,UPDATE,INSERT,DELETE语句。本语言支持条件句法,即IF语句或循环语句(如WHILE和FOREACH)。同时,它还支持调用函数,变量赋值,打印和修改图形数据的功能。

查询正文主体也可以包括对其他查询的调用,即把其他的查询作为该查询的子查询。详见“将查询作为函数”一节。

例:创建查询的语法
CREATE QUERY createQueryEx (STRING uid) FOR GRAPH socialNet RETURNS (int) {
 # declaration statements
 users = {person.*};
 # body statements
 posts = SELECT p
   FROM users:u-(posted)->:p
   WHERE u.id == uid;
 PRINT posts;
 RETURN posts.size();
}  

查询参数以及返回值类型

下表列出了系统支持的输入数据类型和返回值类型:

语句类型(Statement Types)

每条语句就是一条独立指令,描述需要执行的操作。最常见的语句是数据操作语言语句(即DML语句), 它包括了SELECT,UPDATE,INSERT INTO,DELETE FROM和DELETE语句。

GSQL查询有两个级别的语句。上层语句类型称为“查询主体层”语句(query-body-level statement 或 query-body statement )。此类语句是顶层语句块或查询主体控制流语句块的一部分。例如,每个位于最上层的,直接隶属于CREATE QUERY语句块之下的语句,都是一个查询主体层语句。如果其中的一个是含有多个THEN语句块的CASE语句块,则THEN语句块中的每个语句也是一个查询主体层语句。每个查询主体层语句都以分号结尾。

较低级别的语句类型称为“DML-下层”语句(DML-sub-level statement)或简称DML子句。此语句类型用于某些查询主体的DML语句中,以定义特定的数据操作行为。 DML子句以逗号分隔,但语句块中的最后一个DML子句后没有逗号或分号。例如,若一个顶层的语句是SELECT语句,则其ACCUM子句中的每个语句都是DML子句。如果其中一个DML子句是CASE语句,则THEN语句块中的每个语句都是DML子句。

两种语句中的使用有一部分是重合的。例如,assignStmt可以在查询主体层语句中使用,也可以在DML子句中使用。

queryBodyStmts := (queryBodyStmt ";")+
 
queryBodyStmt := assignStmt           // Assignment
              | vSetVarDeclStmt      // Declaration
              | gAccumAssignStmt     // Assignment
              | gAccumAccumStmt      // Assignment
              | funcCallStmt         // Function Call
              | selectStmt           // Select
              | queryBodyCaseStmt    // Control Flow
              | queryBodyIfStmt      // Control Flow
              | queryBodyWhileStmt   // Control Flow
              | queryBodyForEachStmt // Control Flow
              | BREAK                // Control Flow
              | CONTINUE             // Control Flow
              | updateStmt           // Data Modification
              | insertStmt           // Data Modification
              | queryBodyDeleteStmt  // Data Modification
              | printStmt            // Output
              | printlnStmt          // Output
              | logStmt              // Output
              | returnStmt           // Output
              | raiseStmt            // Exception
              | tryStmt              // Exception
 
DMLSubStmtList := DMLSubStmt ["," DMLSubStmt]*
 
DMLSubStmt := assignStmt           // Assignment    
           | funcCallStmt         // Function Call
           | gAccumAccumStmt      // Assignment
           | vAccumFuncCall       // Function Call
           | localVarDeclStmt     // Declaration
           | DMLSubCaseStmt       // Control Flow
           | DMLSubIfStmt         // Control Flow
           | DMLSubWhileStmt      // Control Flow
           | DMLSubForEachStmt    // Control Flow
           | BREAK                // Control Flow
           | CONTINUE             // Control Flow
           | insertStmt           // Data Modification
           | DMLSubDeleteStmt     // Data Modification
           | printlnStmt          // Output
           | logStmt              // Output

如何理解语句类型层次结构:

  • 最上层语句是查询主体层语句(每个语句以分号结尾)。

  • DML中的语句是DML子句(由逗号分隔)。

  • 控制流语句中的语句块与整个控制流语句本身具有相同的类型。

queryBodyStmt和DMLSubStmt之间关系
# Each statement's operation type is either ControlFlow, DML, or other.
# Each statement's syntax type is either queryBodyStmt or DMLSubStmt.
 
CREATE QUERY stmtTypes (parameterList) FOR GRAPH g [
​other queryBodyStmt1;
​ControlFlow queryBodyStmt2   # ControlFlow inside top level.
​​other queryBodyStmt2.1;      # subStmts in ControlFlow are queryBody unless inside DML.
​​ControlFlow queryBodyStmt2.2 # ControlFlow inside ControlFlow inside top level
​​​other queryBodyStmt2.2.1;
​​​other queryBodyStmt2.2.2;
​​END;
​​DML queryBodyStmt2.3     # DML inside ControlFlow inside top-level
​​​other DMLSubStmt2.3.1,   # switch to DMLSubStmt
​​​other DMLSubStmt2.3.2
​​;
​END;
​DML queryBodyStmt3           # DML inside top level.
​​other DMLSubStmt3.1,      # All subStmts in DML must be DMLSubStmt type
​​ControlFlow DMLSubStmt3.2 # ControlFlow inside DML inside top level
​​​other DMLSubStmt3.2.1,
​​​other DMLSubStmt3.2.2
​​,
​​DML DMLsubStmt3.3
​​​other DMLSubStmt3.3.1,
​​​other DMLSubStmt3.3.2
​;
​other queryBodyStmt4;

以下是查询主体层语句的说明:

以下是DML子句中的说明:

安装一个查询

installQuery := INSTALL QUERY [installOptions] ( "*" | ALL | name [, name]* )

执行一个查询之前必须先将其安装。 INSTALL QUERY命令会安装该命令中涉及到的每一个查询,格式为:

INSTALL QUERY queryName1,queryName2,...

它还可以使用以下任何一个命令安装所有已卸载的查询:

INSTALL QUERY * 
INSTALL QUERY ALL 

以下为该命令的两个可选参数:

- force 参数

即使系统提示该查询已安装,也会重新安装该查询。 通过使用这个参数,用户在安装新查询时无需删除之前的旧查询,这对于覆盖已损坏或过时的查询非常有用。 如果未使用此选项,GSQL shell将拒绝重新安装已安装的查询。

- OPTIMIZE 参数

在一个标准的安装过程中,用户自定义查询会动态链接到GSQL语言代码。 每次执行完安装查询命令后,用户可以执行一个INSTALL QUERY –OPTIMIZE命令。 这条命令不需要输入查询的名称。 它会优化所有先前安装的查询,将执行时间缩短约20%。 如果查询执行时间比查询安装的时间对你更重要,则请运行该优化指令。

合规语法:

CREATE QUERY query1... 
INSTALL QUERY query1 
RUN QUERY query1(...) 
... 
INSTALL QUERY -OPTIMIZE    # (optional) optimizes run time performance for query1 and query2 
RUN QUERY query1(...)      # runs faster than before

不合规语法:

INSTALL QUERY -OPTIMIZE query_name

- DISTRIBUTED 参数

如果您具有分布式数据库部署,则以DISTRIBUTED模式安装查询可以提高单个查询的性能 - 使用每个可用计算机中的单个工作程序来生成结果。 某些案例可能会比其他案例从此选项中获益更多 - 更多详细信息可在下一页获得:

INSTALL QUERY -DISTRIBUTED query_name

执行一条查询

安装一条查询会创建一个REST ++访问端点。查询安装后,有两种执行查询的方法。 一种方法是通过GSQL shell: RUN QUERY query_name( parameterValues ) .

CREATE, INSTALL, RUN的例子
CREATE QUERY RunQueryEx(INT p1, STRING p2, DOUBLE p3) FOR GRAPH testGraph{ .... }
INSTALL QUERY RunQueryEx
RUN QUERY RunQueryEx(1, "test", 3.14)

查询输出的大小限制

SELECT语句的结果输出不能超过2GB。 SELECT语句从图中搜索并返回数据,是一个查询最主要部分。 如果SELECT语句的结果大于2GB,则系统将不返回任何数据。 也不会生成任何错误消息。

想要减少查询响应的时间,可以直接向REST ++服务器提交HTTP请求:即向“http://server_ip:9000/query/graphname/queryname”发送GET请求。 如果REST ++服务器是本地的,则server_ip是localhost。 查询参数值可以直接包含在HTTP请求的链接地址中的查询字符串中,也可以使用data payload方式提供。

从TigerGraph v1.2开始,图形名称现在是GET /query URL的一部分。

以下两个curl命令各自等效于上面的RUN QUERY命令。其中,第一个给出了链接地址的查询字符串中的参数值。 此示例展示了原始数据类型的简单格式,例如INT,DOUBLE和STRING等类型。 第二个则通过curl命令的data payload -d选项给出了参数值。

通过HTTP请求执行一个查询
curl -X GET "http://localhost:9000/query/testGraph/RunQueryEx?p1=1&p2=test&p3=3.14"
curl -d @RunQueryExPara.dat -X GET "http://localhost:9000/query/testGraph/RunQueryEx"

其中RunQueryExPara.dat具有与第一个链接地址中的查询字符串完全相同的字符串。

RunQueryExPara.dat
p1=1&p2=test&p3=3.14

要查看用户已经安装了的GSQL查询的参数名称和类型列表,请运行以下REST ++请求:

curl -X GET "http://localhost:9000/endpoints?dynamic=true"

通过使用data payload选项,用户可以避免使用长而复杂的链接地址。 实际上,若想调用相同的查询但使用不同的参数,则只需要更改data payload文件内容即可; HTTP请求可以是相同的。 文件加载器加载整个文件,将多行内容整合到一个文件中,并使用生成的字符串作为链接地址的查询字符串。 如果同时给出了查询字符串和data payload(非常不建议这样使用),则查询字符串中的参数值将覆盖data payload中的值。

复杂类型参数的传递

本小节介绍在通过RUN QUERY或curl命令执行查询时,如何格式化复杂类型的参数值。 有关所有参数类型的更多详细信息,请参见“查询参数类型”一节。

在curl 格式的地址链接中使用方括号时,必须采用-g选项或转义符。 如果参数由data payload(通过文件或payload字符串)给出,则不需要-g选项,并且不需要使用转义符。

下面是一些例子。

通过HTTP请求执行一个查询-复杂参数类型
# 1. SET or BAG
CREATE QUERY RunQueryEx2(SET<INT> p1) FOR GRAPH testGraph{ .... }
# To run this query (either RUN QUERY or curl):
GSQL > RUN QUERY RunQueryEx2([1,5,10])
curl -X GET "http://localhost:9000/query/testGraph/RunQueryEx2?p1=1&p1=5&p1=10"
 
 
# 2. VERTEX.
# First parameter is any vertex; second parameter must be a person type.
CREATE QUERY printOneVertex(VERTEX va, VERTEX<person> vp) FOR GRAPH socialNet {
 PRINT va, vp;
}
# To run this query:
GSQL > RUN QUERY printOneVertex(("person1","person"),"person2")   # 1st param must give type: (vertex_id, vertex_type)
curl -X GET 'http://localhost:9000/query/socialNet/printOneVertex?va=person1&va.type=person&vp=person2'
 
 
# 3. BAG or SET of VERTEX, any type
CREATE QUERY printOneBagVertices(BAG<VERTEX> va) FOR GRAPH socialNet {
 PRINT va;
}
# To run this query:
GSQL > RUN QUERY printOneBagVertices([("person1","person"), ("11","post")])  # [(vertex_1_id, vertex_1_type), (vertex_2_id, vertex_2_type), ...]
curl -X GET 'http://localhost:9000/query/socialNet/printOneBagVertices?va\[0\]=person1&va\[0\].type=person&va\[1\]=11&va\[1\].type=post'
curl -g -X GET 'http://localhost:9000/query/socialNet/printOneBagVertices?va[0]=person1&va[0].type=person&va[1]=11&va[1].type=post'
 
 
# 4. BAG or SET of VERTEX, pre-specified type
CREATE QUERY printOneSetVertices(SET<VERTEX<person>> vp) FOR GRAPH socialNet {
 PRINT vp;
}
# To run this query:
GSQL > RUN QUERY printOneSetVertices(["person3", "person4"])  # [vertex_1_id, vertex_2_id, ...]
curl -X GET 'http://localhost:9000/query/socialNet/printOneSetVertices?vp=person3&vp=person4'

Data Payload文件的大小限制

默认情况下,data payload选项支持的文件最大为128MB。若要提高该大小限制,则可以运行以下命令:

gadmin --set nginx.client_max_body_size xxx -f

此设置的上限为1024 MB。 增加payload缓冲区的大小限制,会减少可用于其他操作的内存空间,因此提高此限制时请谨慎。

有关REST ++访问端点的更多详细信息,请参阅“RESTPP API用户指南”。

运行查询时,以下选项可用:

所有顶点模式 (-av 选项)

某些查询会让SELECT语句中在所有顶点或几乎所有顶点上执行,例如 PageRank命令。 在这种情况下,图形处理引擎可以在全顶点模式下更有效地运行。 在全顶点模式中,系统始终选择所有顶点,同时以下操作无效:

  • 按照指定的顶点或顶点类进行过滤。 源顶点集必须是所有顶点。

  • 使用WHERE子句进行过滤。

  • 使用HAVING子句进行过滤。

  • 对特定的顶点或顶点类赋值。 例如:X = { vertex_type .*}

要以全顶点模式运行查询,请在shell模式下使用-av选项,或在HTTP请求的查询字符串中包含__GQUERY__USING_ALL_ACTIVE_MODE=true参数。

GSQL > RUN QUERY -av test()
 
## In a curl URL call。Note the use of both single and double underscores.
curl -X GET 'http://localhost:9000/query/graphname/queryname?__GQUERY__USING_ALL_ACTIVE_MODE=true'

诊断(-d选项)

用户可以打开诊断选项以生成诊断监视日志,该日志包含每个SELECT语句的处理时间。 要打开监视日志,请在shell模式下使用-d选项,或在HTTP请求的查询字符串中使用__GQUERY__monitor = true参数。

GSQL > RUN QUERY -d test()
 
## In a curl URL call。Note the use of both single and double underscores.
curl -X GET 'http://localhost:9000/query/graphname/queryname?__GQUERY__monitor=true'

生成日志文件的地址会作为输出消息的一部分。下面的例子展示了输出的样式:

Query Block Start (#6) start at 11:52:06.415284
Query Block Start (#6) end   at 11:52:06.415745 (takes 0.000442 s)
 
Query test takes totally 0.001 s (restpp's pre/post process time not included)
---------------- Summary (sort by total_time desc) ----------------
 
Query Block Start on Line 6
----------------------------------------------------------
 total iterations count      : 1
 avg   iterations stats      : 0.000442s
 max   iterations stats      : 0.000442s
 min   iterations stats      : 0.000442s
 total activated vertex count : 2
 max   activated vertex count : 2
 min   activated vertex count : 2

GSQL查询的输出格式

GSQL查询的输出遵循业界标准的JSON格式。JSON对象是一个无序的键值对集合,并用大括号括起来。JSON值接受的数据类型为数组或对象。JASON数组是一个有序的值列表,用方括号括起来。由于值可以是对象或数组,所以JSON是可以嵌套的。字符串用双引号括起来。同时,我们用字段(field)一词来表示某个指定对象的键(或键值对)。

在JSON结构的最上层是三个必填字段:错误(error), 消息(message)和结果(results)。如果查询成功,则错误值将为false,消息值为空,结果值为查询的预期输出。如果在查询执行期间发生错误或异常,则错误值为true,消息值将是描述消息,而结果值为空。

在v2版的标准的输出规范中,增加了一个额外的最上层字段:版本(version)。 版本值也是一个对象,包含以下内容:

在某些情况下,可能会出现其他一些最上层的对象,例如“代码”(code)。 请注意,最上层对象需要用大括号括起来,这意味着它们形成了无排列顺序的元素集合。 即它们的元素可以按任意顺序排列。

下面是示例展示了一个成功的查询和输出:

例: 一个顶层的JSON格式查询输出
{
 "version": {"api": "v2","schema": "1"},
 "error": false,
 "message": "",
 "results": [
   {results_of_PRINT_statement_1},
   ...,
   {results_of_PRINT_statement_N}
 ]
}

“结果”键值对输出的是一张包含许多数据对象的列表,按照PRINT语句执行的顺序排序。PRINT语句结果的详细格式在“输出语句”一章中详述。

为了向下兼容,TigerGraph平台即可使用v2版本的API,也可以使用v1版本的API生成输出。

修改默认输出API的版本

以下GSQL语句可用于设置输出API的版本。

SET json_api = <version_string>

目前,<version_string>的值只能用“v1”和“v2”。 此语句设置一次,永久生效。 默认情况下,每个版本的TigerGraph平台都会将输出API预设为最新的版本。 例如,平台版本1.1中,每个查询默认都生成v2版本API的输出。

显示查询内容

要显示查询的具体内容,请运行“SHOW QUERY query_name”命令。 此外,“ls”命令可以用于列出所有已创建的查询,并标识已安装的查询。

删除查询

要删除查询,请运行“DROP QUERY query_name”命令。该命令会卸载已安装的查询并从字典中将其删除。 但假设有一个查询R调用了查询Q,则GSQL语言将拒绝删除已安装的查询Q。 也就是说,必须先删除调用该查询的上一级查询或同时删除所有有调用关系的查询。

要删除所有查询,可以使用以下任一命令:

DROP QUERY ALL 
DROP QUERY *

ALL的作用范围

Last updated