WITH 可以对别名进行函数运算,并将结果传递给后面的语句。输入中有异源别名时,对异源别名按行进行笛卡尔乘积组合。
语法:with <expression>
as <alias>
, <expression>
as <alias>
, ...
参数:
- <expression>:别名的运算表达式
- <alias>:运算结果的别名,可省略
WITH 子句中对某别名去重时,其同源别名也一同去重。
find().nodes() as n1 limit 2
n(3).e()[2].n(as n2) as path
with pnodes(path) as array, distinct(n2.color) as colors
with n1, array
return n1, array, colors
上面 UQL 代码中的第一个 WITH 子句对别名 path 进行函数运算得到同源别名 array,对 n2 的 color 属性去重得到同源别名 colors,该去重操作还影响了 path、array 和 n2 这些同源别名;第二个 WITH 子句将异源别名n1 和 array (以及 array 的同源别名 color 等)按行进行了笛卡尔乘积:
传递一个别名
示例:找出级别最高的银行卡
find().nodes({@card}) as n1
with max(n1.level) as maxLevel
find().nodes({@card.level == maxLevel}) as n2
return n2{*}
传递异源别名(笛卡尔积组合)
示例:将数列 1、2、3 与数列 4、5 进行笛卡尔乘积,以表格形式返回
uncollect [1,2,3] as a1
uncollect [4,5] as a2
with a1, a2
return table(a1, a2)
示例:找出拥有银行卡 CA001、CA002、CA003 的顾客,找出品类为 book 的商品,查找这些顾客对这些商品的购买、浏览路径
khop().n({_id in ["CA001","CA002","CA003"]}).e({@has}).n({@customer}) as n1
n({@prodCAT.name == "book"}).e().n({@product} as n2)
with distinct(n1)
with n1, n2
n(n1).e({@buy || @view}).n(n2) as p
return p{*}
分析:查找多张银行卡的使用者时需注意去重;WITH 子句中进行 distinct() 去重运算时不能接收异源别名的传入;本例中 WITH 子句对 n1、n2 进行笛卡尔积的效果与组网查询中的互组网功能类似,本例等效于:
khop().n({_id in ["CA001","CA002","CA003"]}).e({@has}).n({@customer}) as n1
n({@prodCAT.name == "book"}).e().n({@product} as n2)
with collect(distinct(n1)) as a1
with a1, collect(n2) as a2
autonet().src(a1).dest(a2).depth(1) as p
return p{*}
复杂语句 with 举例
示例:分别找出向银行卡 CA021、CA022、CA029 转账的银行卡,找出这三组银行卡各自的级别最高的卡,将卡号合并为数组后与收款卡对应返回
n({_id in ["CA021","CA022","CA029"]} as payee).le({@transfer}).n({@card} as payer)
with payee, payer
group by payee
with max(payer.level) as maxLevel
n(payee).le({@transfer}).n({@card.level == maxLevel} as topPayer)
group by payee
return payee, collect(topPayer)
分析:第一个 WITH 子句的作用是在 V4.0 版本中延长别名 payee、payer 在整个 UQL 语句中的声明周期,在 V4.1 版中该子句可以省略。