概述
一个UQL语句通常包含多个子句,它们将从数据库获取或自行构建的数据按顺序进行传递和处理。别名通常用于命名和代表数据,以便后续子句调用数据。
一个数据可以包含多个条目。为了便于说明,我们将其视为包含多个数据行,每行包含一个数据条目。当子句(尤其是链式子句)调用别名时,将逐行执行相应的查询或计算。
同源数据
由同一子句产生的数据是同源的,流入子句的数据与子句产生的数据也是同源的。同源数据的特点是数据行数相等,并且同一行有对应关系。这种同源特性也延申到从一个数据提取出的信息。
示例:tail
、path
和length
是同源的,它们都包含5行数据。
n().e()[:2].n(as tail).limit(5) as path
with length(path) as length
return path, tail, length
示例:n
、n.score1
、n.score2
和mean
是同源的,它们都包含4行数据。
find().nodes() as n
return (n.score1 + n.score2) / 2 as mean
聚合
使用聚合函数会使数据只剩一行,其余行被丢弃,此时同源数据也会被影响。聚合后,所有同源数据剩余的一行通常没有对应关系。
示例:n
和n.score1
同源,原本包含4行数据;当n.score1
在RETURN
子句中被聚合并产生minS1
后,n
也只剩1行。
find().nodes() as n
return n, min(n.score1) as minS1
去重
对数据进行去重通常会使数据行变少,此时同源数据也会被影响。所有同源数据剩余的数据行仍保有对应关系。
在RETURN
子句中进行去重时,情况却有所不同,此时同源数据不受影响。因此,数据行之间的对应关系可能丢失。
示例:tail
和path
同源,原本包含5行数据。
- (a):在
WITH
子句中对tail
进行去重,path
中相应的数据行也被丢弃。 - (b):在
RETURN
子句中对tail
进行去重,path
不受影响。
异源数据
由完全独立的不同子句产生的数据是异源的。异源数据通常数据行数不等,同一行数据也没有对应关系。
当异源数据流入同一子句时,它们通常会被自动裁剪至所有数据的最小长度,以确保它们可以被逐行处理。然而,此规则有两个特例:
WITH
子句会对异源数据执行笛卡尔乘积处理。RETURN
子句不对异源数据进行长度对齐裁剪,除非它们共同用于某些计算,或者包含聚合函数,
示例:n1
和n2
是异源的,数据行数不等;它们被共同用于路径查询子句,因此n2
的第三行被丢弃,以保证n1
和n2
行数相等。
find().nodes({_uuid in [1, 3]}) as n1
find().nodes({_uuid in [2, 4, 5]}) as n2
n(n1).e().n(n2) as path
return path
WITH子句
示例:a
和c
同源,包含3行数据,它们与包含2行数据的b
异源;WITH
子句对c
和b
执行笛卡尔乘积,最后c
和b
都包含6行数据。
RETURN子句
示例:包含3行数据的a
与包含2行数据的b
异源。
- (a):
RETURN
子句单独对b
进行计算,不影响a
,最后a
返回3行数据,b+1
返回2行数据。 - (b):
RETURN
子句计算c
时需要对a
和b
进行长度对齐裁剪,因此c
只包含2行数据;单独返回的a
和b
不受影响。
示例:RETURN
子句对a
进行聚合,造成b
也只剩1行数据。