使用参数化GSQL查询进行查询
我们刚刚看到运行简单的内置查询是多么简单和快捷。然而,您无疑希望创建自定义或更复杂的查询。GSQL通过参数化的顶点集查询将最大的权力交给您。参数化查询允许您遍历从一个顶点到相邻的顶点集的图,一次又一次地执行计算过程,内置并行执行和方便的聚合操作。您甚至可以让一个查询调用另一个查询。我们从简单的学起。
写一个GSQL参数化查询有三个步骤。
在GSQL中定义查询。这个查询将被添加到GSQL目录中。
在目录中安装一个或多个查询,为每个查询生成一个REST端点。
运行已安装的查询,提供适当的参数,可以调用GSQL命令,也可以通过向REST端点发送HTTP请求。
一个简单的1-Hop查询
现在,让我们编写第一个GSQL查询。我们将显示作为输入参数的人的所有直接(1-hop)邻居。
此查询具有一个SELECT语句。这里的SELECT语句比内置查询中的语句强大得多。在这里,您可以执行以下操作:查询开始时,通过从查询调用传入的参数p所标识的person顶点,将一个顶点集“Start”设置为“Start”。大括号告诉GSQL构造一个包含所包含项目的集合。
接下来,SELECT语句根据FROM子句中描述的模式描述了1跳遍历:
Start:s -(friendship:e)- >person:tgt
这基本上与我们用于内置select edges查询的语法相同。也就是说,我们从给定的源集(Start)中选择所有的边,这些边具有给定的边类型(friendship),并以给定的顶点类型(person)结束。我们以前没有见过的一个特性是使用“:alias”: “s”是顶点集别名,“e" 是边集别名,“tgt”是目标顶点集别名。
返回到初始子句和赋值(“Result = SELECT tgt”)。这里我们看到目标集的别名tgt。这意味着SELECT语句应该返回目标顶点集(通过SELECT查询块中的完整子句集进行过滤和处理),并将该输出集分配给名为Result的变量。
最后,我们打印出JSON格式的结果顶点集。
创建一个查询
与其在交互模式中定义查询,不如将查询存储在一个文件中,并使用@filename语法从GSQL shell中调用该文件。将上面的查询复制并粘贴到文件/home/tigergraph/hello.gsql中。然后,进入GSQL shell并使用@hello调用该文件(注意,如果您在开始gsql时没有在/home/tigergraph文件夹中,那么您可以使用绝对路径来调用gsql文件。例如@/home/tigergraph/hello.gsql)。然后运行“ls”命令,查看新加的查询现在在目录中了。
安装一个查询
但是,查询尚未安装;它还不能运行。在GSQL shell中,输入以下命令来安装刚刚添加的查询“hello”:
数据库安装这个新查询大约需要1分钟。要有耐心!
对于大型数据集上的查询,这种小的投资可以在更快的查询执行中获得多次回报,尤其是在使用不同参数多次运行查询时。安装将生成机器指令和一个REST端点。当进度条达到100%后,我们就可以运行这个查询了。
在GSQL中运行查询
要在GSQL中运行查询,请使用“run query”,后跟查询名和一组参数值:
结果以JSON格式显示。Tom有两个一步邻居,即Dan和Jenny。
将查询作为REST端点运行
在后台,安装一个查询还会生成一个REST端点,这样就可以通过http调用来调用参数化查询。在Linux中,curl命令是提交http请求的最流行的方式。在下面的示例中,所有查询的标准部分用粗体显示;正常权重中的部分属于这个特定的查询和参数值。JSON结果将返回到Linux shell的标准输出。因此,我们的参数化查询变成了http服务!
最后,要查看目录中查询的GSQL文本,可以使用:
恭喜你! 至此,您已经完成了定义、安装和运行查询的整个过程。
一个更高级的查询
现在,让我们执行一个更高级的查询。这一次,我们将学习如何使用强大的内置累加器,它充当在图中遍历过程中访问的每个顶点的运行时属性。运行时意味着它们只在查询运行时存在;它们被称为累加器,因为它们是专门用来在查询的隐式并行处理过程中收集(积累)数据的。
在这个查询中,我们将找到所有与参数化输入人员两步距离的人。为了好玩,我们来计算一下这些2跳邻居的平均年龄。
在这种图遍历算法的标准方法中,您使用一个布尔变量来标记算法“访问”一个顶点的第一次,这样它就知道不再计算它了。为了满足这一需求,我们将定义一个OrAccum类型的本地累加器。要声明本地累加器,我们在标识符名称前面加上一个“@”符号。每个累加器类型都有一个默认的初始值;布尔累加器的默认值为false。可以选择指定初始值。
我们还需要计算一个平均值,因此我们将定义一个全局AvgAccum。全局累加器的标识符以两个“@”开头。
定义了开始集之后,我们就有了第一个单跳遍历。SELECT和FROM子句与第一个示例相同,但是还有一个附加的ACCUM子句。ACCUM子句中的+=运算符意味着,对于匹配FROM子句模式的每条边,我们将右手边的表达式(true)累加到左手边的累加器(tgt.@visited以及s.@visited)。注意,可能会多次访问源顶点或目标顶点。参照图1,如果我们从顶点Tom开始,会有两个边事件发生,所以第一个SELECT语句中的ACCUM子句会访问Tom两次。由于累加器类型是OrAccum,两遍历的累积效应如下:
Tom.@visited <==(initial value:false)OR (true)OR(true)
请注意,先处理两条边中的哪一条并不重要,因此此操作适合多线程并行处理。最终的结果是,只要访问一个顶点至少一次,它就会以@visited = true结束。第一个SELECT语句的结果被分配给变量FirstNeighbour。
第二个SELECT块将进一步执行一跳,从FirstNeighbor顶点集变量开始,并到达2跳的邻居。注意,这一次,我们在FROM子句中省略了edge类型friendship和目标顶点类型person,但是保留了别名。如果没有提到别名的类型,则将其解释为所有类型。由于我们的图只有一个顶点类型和一个边缘类型,所以逻辑上它与我们指定的类型相同。WHERE子句过滤掉之前被标记为已访问的顶点(1跳邻居和起始顶点p)。这个SELECT语句使用POST_ACCUM而不是ACCUM,原因是POST_ACCUM会遍历顶点集而不是边集,保证我们不会重复计算任何顶点。在这里,我们计算2跳邻居的年龄,得到他们的平均年龄。
最后,p的第二个邻居被打印出来。
这次,我们将以下所有GSQL命令放入一个文件hello2.gsql:
USE GRAPH social
查询定义
安装查询
运行查询
我们可以在不输入GSQL shell的情况下执行这一完整的命令集。请将上面的GSQL命令复制并粘贴到一个名为/home/tigergraph/hello2.gsql的Linux文件中。
在Linux shell中,在/home/tigergraph下,输入以下内容:
结果如下所示。
查询方法总结
查询被安装在目录中,可以有一个或多个输入参数,从而可以重用查询
GSQL查询由一系列SELECT查询块组成,每个查询块生成一个指定的顶点集
每个SELECT查询块都可以开始从前面定义的任何顶点集遍历图形(也就是说,序列不必形成一个线性链)
累加器是具有内置累加操作的运行时变量,用于高效的多线程计算
输出是JSON格式。
Last updated