概述
别名(Alias)是给UQL语句执行过程中产生的数据起的名字,定义别名是为了后续的数据调用以及返回。
别名
自定义别名
别名定义
UQL使用关键词as
自定义别名。使用时需注意:
- 别名要在数据产生的子句中进行定义。
- 别名可以被重命名,重命名后之前定义的别名名称不再有效。
- 一个别名名称在一个UQL语句中只能使用一次,由于重命名而失效的别名名称在同一语句中也不能再次使用。
在UQL语句中,如果获取了数据但未定义别名进行使用,或是定义一个别名但后续不使用或返回该别名,都可能会影响语句的执行效率。
别名命名规则
自定义别名由用户命名,规则如下:
- 1~64个字符
- 不以波浪号(~)开头
- 不包含反单引号(`)
- 不使用系统保留字
别名中含有除数字、字母、下划线以外的字符(包括中文字)时,在UQL语句中使用时需要用一对反单引号(`)包裹,示例如下:
find().nodes() as `电影`
return `电影`
自定义别名应尽量避免与点、边的属性重名。无法避免时可使用系统别名this消除歧义。
系统别名
UQL有三个系统别名:
系统别名 | 使用位置 | 代表的数据 |
---|---|---|
this |
任意点、边过滤器 | 当前点或边 |
prev_n |
点、边模板的过滤器 | 当前点或边的前一个点 |
prev_e |
点、边模板的过滤器 | 当前点或边的前一个边 |
this
在点、边过滤器中,this
用于指代点或边通常是可以省略。例如,以下语句中的点过滤器{balance > 5000}
实际上是{this.balance > 5000}
的简写。
find().nodes({balance > 5000}) as n
return n
但如果存在歧义,this
则不能省略。常见情况是,有自定义别名与点或边属性重名。在以下语句中,别名balance同时也是一个点属性名称,在过滤器中使用{this.balance > 5000}
即明确使用属性balance。此时若写为{balance > 5000}
,系统使用别名balance作为过滤条件。
... as balance
find().nodes({this.balance > 5000})
...
prev_n
prev_n
只能在点、边模板中使用,指路径中位于当前点或边左侧最近的一个点。
- 在单边、单点模板中使用:

如果在路径模板的起点
n()
中使用prev_n
,prev_n
指代的节点实际上不存在。此时,与该prev_n
有关的==
、!=
、>
、>=
、<
、<=
条件判断返回真,使用其他操作符的判断结果不可预期。
- 在多边模板中使用:

需要强调的是,prev_n
指代的所有节点都必须具有prev_n
调用的属性。考虑以下示例,该语句搜索“@actor - [@actsIn] - @movie”路径并要求@movie节点的rating超过@actor节点。此时,如果@actor没有rating属性,查询将不会得到任何结果。
n({@actor}).e({@actsIn}).n({@movie.rating > prev_n.rating})
return p{*}
prev_e
prev_n
只能在点、边模板中使用,指路径中位于当前点或边左侧最近的一条边。
- 在单边、单点模板中使用:

- 在多边模板中使用:

如果在路径模板的第一个
n()
、e()
或e()[<>]
中使用prev_e
,prev_e
指代的(第一条)边实际上不存在。此时,与该prev_e
有关的==
、!=
、>
、>=
、<
、<=
条件判断返回真,使用其他操作符的判断结果不可预期。
需要强调的是,prev_e
指代的所有边都必须具有prev_e
调用的属性。考虑下面的示例,该语句搜索“holder - [@holds] - @card - [@transfersTo] - @card - [@transfersTo] - @card - [@holds] - holder”路径并要求转账时间越来越晚。然而,由于prev_e
也包括第一条@holds边,如果@holds没有time属性,查询将不会得到任何结果。
n({@user} as holder)
.e({@holds}).n({@card})
.e({@transfersTo.time > prev_e.time})[:2]
.n({@card}).e({@holds})
.n(holder) as p
return p{*}
默认别名
UQL有两个默认别名:
默认别名 |
应用位置 | 代表的数据 |
---|---|---|
nodes |
find().nodes() 子句 |
获取的点 |
edges |
find().edges() 子句 |
获取的边 |
默认别名无需定义,可直接使用:
find().nodes({@account})
return nodes{*}
然而,如果选择自定义别名,默认别名不再有效。
子句别名和方法别名
在一些UQL子句中,支持为整个子句定义别名(称为子句别名),以及为部分方法定义别名(称为方法别名)。详见各子句的语法介绍。
本例为find().edges()
子句定义别名:
find().edges({@direct}) as e
return e
不支持为find()
或edges()
方法单独定义别名。
本例同时为autonet().src().dest().depth()
子句及其方法src()
定义别名:
autonet().src({age < 60} as startNodes).dest({@event}).depth(:3) as paths
return startNodes, paths
本例分别为find().nodes()
子句和WITH
子句定义别名:
find().nodes({@account}) as a
with min(a.age) as minAge
find().nodes({@account.age == minAge}) as b
return b.name
别名类型
别名的类型取决于它代表的数据。以下示例定义和调用了多个别名:
- 别名users代表点,类型是NODE。
- 别名maxAge代表age属性的最大值,可能是某种数值类型,比如int32或int64。
- 别名signups代表边,类型是EDGE。
- 别名p代表路径,类型是PATH。
find().nodes({@user}) as users
with max(users.age) as maxAge
n({@user.age == maxAge}).e({@signsUp} as signups).n({@course}) as p
return signups, p
别名调用
根据别名类型,你可以在特定子句中直接调用别名,或从别名中提取特定信息来使用。
下表是不同类型别名的调用格式示例:
*注:示例别名nodes
、edges
、paths
、myLists
、myPoints
、myObjects
和myItems
分别代表类型为NODE、EDGE、PATH、list、point、object及其他类型的数据。
调用格式 |
代表的数据 | 数据类型 |
---|---|---|
nodes |
点 | NODE |
nodes.name |
点的name属性值 | 与name属性类型一致 |
nodes.@ |
点schema | string |
edges |
边 | EDGE |
edges.time |
边的time属性 | 与time属性类型一致 |
edges.@ |
边schema | string |
paths |
路径 | PATH |
myList |
整个列表 | list |
myList[2] |
下标为2的元素 | 与该元素类型一致 |
myList[0:3] |
由下标为0~3的元素构成的列表 | list |
myList[:5] |
由下标为0~5的元素构成的列表 | list |
myList[2:] |
由下标为2至最后的元素构成的列表 | list |
myPoint |
整个坐标 | point |
myPoint.x |
坐标x | double |
myPoint.y |
坐标y | double |
myObject.age |
键age的值 | 与键age的类型一致 |
myItem |
数据本身 | 与该数据的类型一致 |
UQL不支持调用TABLE类型的别名。
RETURN
子句支持更多形式的别名调用,详情请参考这里。