数据流就是 UQL 运行时产生的结果,包含多行数据,像水流一样从一个语句流出,并以迭代的方式一行行地流入后面的语句。
同源流
同一个查询产生的多个结果,以及这些结果被调用、运算后得到的结果都是同源的。同源流的数据行数是相等的,各个流在同一行中的数据有对应关系。
下图中的路径 path,路径的终点 tail、路径的长度 length 是同源的,都含有 5 行数据:
大部分表达式在调用同源流时,在每一行内调用各个流的数据进行运算,并且逐行执行。
下图中的同源流 nodes.score1、 nodes.score2 经过表达式运算后得到同源流 mean:
在 WITH 子句中对某个流去重时,其同源流的相应行会受影响;在 RETURN 子句中对某个流去重时,其同源流不受影响。下图中的 (a)、(b) 分别展示了这两种情况。
异源流
不同查询产生的结果是异源的,即非同源的。异源流的数据行数通常不相同,各个流在同一行中的数据也没有对应关系。
下图中的 a,b 不同源,数据行数分别为 3 和 2:
一个表达式调用异源流时,如果表达式位于 WITH 子句中,会先进行笛卡尔乘积后再逐行计算,否则会按照最短流的长度(行数)进行裁剪后再逐行计算。下图中的 (a)、(b) 分别展示了这两种情况。
无论何种情况,异源流在共同经过了表达式的运算后,都转变为同源流。
子查询
数据流进入链式语句(增删改查)时,语句执行的次数等于数据流的行数,每次使用一行数据(系统会根据实际情况进行优化)。
这里所说的数据流的行数,对于进入查询语句的同源流来说,就是同源流本来的长度;对于异源流来说,是最短流的长度。
下图中的 n 进入了删除语句,该删除语句共执行 4 次,每次删除一个点:
当数据流进入一个查询语句时,称该查询语句的每一次执行为一个子查询。
下图中的红、蓝两个节点 n 共触发了 2 次 find().nodes()
子查询,第一次查到三个红色节点,第二次查到两个蓝色节点,总的 result 共 5 个:
子句 CALL、前缀 OPTIONAL、参数 limit()
能够对每个子查询的结果进行单独处理。其余的子句、函数均只能对所有子查询结果的总和(即该查询语句的整个结果)进行处理。下图中的 (a)、(b) 分别使用 limit()
和 LIMIT 对每个子查询的结果、整个查询的结果进行限长。