00:00
到目前为止呢,关于link CQ的基本用法我们就都已经了解了,那接下来呢,我们还要专门的再用一节来讲解一下link c当中的函数。其实关于函数这个概念我们并不陌生啊,那其实在所有的编程语言里面啊,都有类似的概念啊,那当然了,在Java里面可能把它叫做方法啊,都是基于这个对象去调用的一个方法,那其实本质上都是一样的,所谓的函数function其实我们知道啊,就是把一些操作,把一些代码包装起来,完成某个固定的功能啊,那对于函数呢,有可能还需要去传入一些参数,有一些输入的数据,然后得到结果呢,有可能还要作为返回值返回啊,这就是我们所说的一个函数的功能。他可以认为就是一段代码块的包装,那在CQL当中同样也有类似的定义,我们也是可以把一些数据的转换操作包装起来啊,本质上来讲它是针对数据的一个转换,那调用的时候呢,就直接可以把它嵌入到cqu当中统一去使用。
01:08
诶,那其实对于flink CQ而言啊,也是同样提供了这样的一个功能,那么flink里边呢,它包含了table API和CQ2种实现形式,所以在调用的时候也会有所不同,我们知道table API本身啊,它是内嵌在编程语言里面的,所以呢,它要去使用函数的时候,哎,那其实是通过我们要操作的那个数据对象调一个方法来进行实现。而CQL当中呢,CQL当中就非常简单了,就是直接引用函数的名称,然后呢,要操作的数据作为参数传进去,比如说哎,这里我们要把一个字符串string啊,转换成一个全大写的形式啊,那我们知道这个string本身在Java或者scale里边,它就是一个字符串对象嘛,啊,那在table API里边的写法呢,那就是直接调用这个对象的upper case方法。
02:00
而CQ里面的写法,那就是调用upper这样一个函数,然后把string作为参数传进去就可以了啊,所以呃,就是对于这个table API和CQ的两种用法呢,就看我们到底是习惯去使用哪一种,其实因为table API它是内嵌在编程语原理的,所以很多方法你要使用的时候是比较麻烦的啊,它是需要在类里边额外添加的,所以呢,这个扩展就不太方便,目前它支持的函数也是比较少的,就不如CQ啊本身支持的多,所以一般情况下我们在应用的时候都是直接用CQ里面的函数就可以了,所以后面我们的介绍都是以这个CQ里面的调用为准。关于弗link CQ里边的函数呢,整体来讲我们可以分成两大类,一大类那是CQ里边内置的系统函数,也就是说,哎,不用我们单独去实现啊,这个名称就像一个关键字一样,直接拿来就可以用了啊,往往我们看为了看清楚会把它做一个大写啊,直接通过函数名调用就可以了,像之前我们在统计每一个用户访问URL次数的时候,用的这个count做了一个聚合统计,这其实就是一个函数嘛,所以对于一般的需求,我们直接调用这样的函数就可以了。那还有另外一类呢,就是系统没有直接帮我们实现的一些功能,那就需要我们去做一个自定义,那就是用户自定义的函数,这个函数呢,因为系统没办法直接识别,所以我们自己定义出来之后,哎,那往往就是自己实现了一个类了啊啊,然后可能要创建它对应的一个对象,还需要在表环境里边做一个函数的注册。接下来才可以使。
03:46
啊,所以接下来我们就对这两类函数分别做一个介绍,首先就是所谓的系统函数了,系统函数呢,也叫做内置函数,就是built in function,就是它内嵌在系统里边的,预先已经给我们准备好了相应的功能,所以调用的时候呢,直接根据函数名调就可以了,里边可能需要我们传入一些参数,哎,那要求传什么参数,我们直接把对应的数据准备好放在里边就可以嵌在CQ查询里了。
04:16
啊,那对于福CQ而言呢,它其实几乎已经支持了所有标准CQ里面的操作了啊,所以呃,这也是为什么我们在实际的工作当中啊,呃,使用这个上层的API,使用Li SQ会越来越多,因为这个现成的函数都有啊,很多常规的功能我们直接调用函数就直接搞定了。那Li CQ给我们实现的系统函数呢,主要又可以分成两大类啊,一大类是标量函数,另外一大类呢是聚合函数,它们主要的区别是什么呢?哎,从名字上我们就可以看得出来啊,标量什么叫标量?哎,在物理上我们知道所谓的标量它是针对矢量而言的,标量就是只有数值大小,没有方向的量,哎,那所以标量函数呢,指的就是只针对输入的数据做一些转换计算,然后呢,就返回一个固定等值哎这样的函数,这就是所谓的标量函数,哎,所以如果说啊,我们应用了一个标量函数的话,它可能就需要传入参数了,需要传入的参数就是我们针对处理的这个数据,如果我们把它应用在一张表里边的话,那就相当于是针对这个表里边的每一行数据,然后呢,把要操作的那个数据字段要提取出来,然后传给这个标量函数,经过转换之后就得到了对应的一个结果,诶。
05:37
所以它的转换可以认为就是一个一对一的转换,有点像我们在流数理里边data stream API里面的map操作啊,那另外还有就是说有一些标量函数呢,那甚至连这个输入参数都不需要有啊,这个输入参数可以有多个,也可以有一个,也可以没有啊,就是没有参数的时候,直接也可以一调用就得到一个唯一的结果,它也是标量函数。
06:02
这里需要注意,就是我们所说的这个一对一啊,这样一个map指的是对于当前数据的处理,而并不是说当前这个函数的参数,这个函数可以有多个参数啊,我们说也可以没有嘛,那所谓的这个函数参数其实是要在当前这条数据里边,可能需要去提取不同的字段作为多个参数。啊,那所以我们要把这个概念搞清楚。标准函数其实是非常常见啊,也最简单的一类系统函数了,数量可以说是非常非常的多啊,那这一部分内容呢,我们可以到官网上啊去做一个完整的考察啊,那我们点进去啊,在官网上点到table API和CQ这一部分里边来,然后找到functions下边有一个system functions啊,也就是built in啊内置的函数,我们看到这里面的函数,这个数量其实是非常非常多啊,所有的函数的名称功能啊,这这里边有两种方式,就是CQ里边的调用方式和table API里面的调用方式啊,都有对应的实现,然后它的描述说的非常的详细,如果我们想要去了解的话,可以查看官网,那这里呢,我们就简单的做一个大概的介绍啊呃,那整体来讲,标量函数可能可以分成这样的几类,比如说呃,有这个比较函数。
07:20
比较函数非常容易理解啊,本质上来讲就是一个比较表达式,主要就是要判断两个值之间的关系,它的返回结果呢,那就是一个布尔类型的值,那这个比较表达式其实啊,我们也可以不做函数调用,你就直接做一个相等啊,两个值Y61等于Y62,这其实也是一个比较判断嘛,哎,所以它本质上底层就是一个比较函数啊,那另外呢,判断两个值不等怎么办呢?哎,那就可以小于大于啊,那可以小于也可以大于,那其实就是说它俩不相等啊啊另外还可以用一些类似于文字的这样一些描述,比如说value is not not,哎,那就是判断当前这个值是否不为空,如果不为空的话,就返回处。
08:04
这是比较函数,另外还有一类呢,是逻辑函数,逻辑函数其实就是在比较函数的基础上又加了一个逻辑组合,所以它就是一个逻辑表达式,把前面我们这个返回布尔类型的一些比较判断啊,各种各样的这个布尔类型的值,用与或非and or not把这些值连接起来啊,那或者呢,也可以用这个判断语句做这个真值判断啊,就是is is not这些都可以把这些判断出来的逻辑结果除false的结果做一个连接,这就是所谓的逻辑函数。啊,这个本身也非常的简单啊,呃,我们就不再详细去展开了,另外还有就是算术函数,算术函数这个也很简单,加减乘除嘛,做各种各样的算术计算,呃,那包括一些复杂的数学运算,其实也都是可以通过函数调用去实现的。啊,最简单的这个加减乘除的这种连接啊,我们可以认为它底层也是一个算术函数,那另外呢,比方说像这个抛二啊,那抛二传入两个数进来,其实就是要做一个幂运算,取第一个数的啊,然后指定第二个数,这么多次方的一个幂运算啊,那另外还有像这个run啊,Run我们知道它没有参数,直接就返回一个0.0~1.0区间内的一个double类型的尾随机数,它是一个随机数的生成器。
09:27
好,前面的这些内容都比较简单,后边的话可能我们在实际应用的过程当中就会应用的更多了,比如说字符串的函数,它主要就是针对字符串进行处理啊,那我们看这个字符串函数呢,有些操作就会跟一些类似于逻辑判断呀,或者其他的一些这个符号啊,就会混淆,比方说像一个string后边加两个竖线。就像我们在这代码里边的逻辑或判断一样啊,然后跟着另外一个string,这表示什么呢?这表示的就是两个字符串的一个连接,一个拼接操作啊,那另外前面我们说过了啊,如果说想要把这个字符串直接全转化为大写,哎,那直接upper调这个函数就可以,那还有像这个叉lengths直接计算当前字符串的长度啊,这个在有些场景下啊,应用也非常的广泛。
10:19
另外还有一大类呢,就是所谓的时间函数,它主要就是进行跟时间相关的操作了啊,那比如说非常简单的啊,Date后面跟一个string,这就是要返回一个CQ的date类型啊,返回一个日期了,哎,它主要呢,就是按照年月日这样的一个格式去解析这个字符串,把它解析出一个CQ的date类型。啊,那同样呢,我们也可以解析出一个time step类型,比如说这里边定义的就是time后面跟一个string,这里注意啊,这里的string呢,格式又不一样,它必须是年月日十分秒这样的格式啊,那我们也可以没有任何的参数,直接来一个current time,那它返回的是本地时区的当前时间。
11:03
那另外还有一个我们非常熟悉的啊,就是interval后面跟上string和range,它返回的就是一个时间间隔,前面我们定义时间窗口长度的时候啊,或者说我们在指定当前这个水位线延迟时间的时候啊,只要涉及到一段时间,用的都是这样的一个语法啊,它的本质啊,底层也是一个时间函数,这里我们需要注意的是,Interval后边跟着的是一个string,这个string呢,我们知道它其实表示的是一个数值啊,那这里我们是要引起来使用一个字符串来表示数值,最后跟着的是一个range,这个range我们可以理解成一个时间单位了啊,那可以是比方说day hour minute second这样的时间单位,也可以是。Year two months这样的复合单位,那什么叫做year to month呢?啊,简单来说就是这可以认为是我们要指定一个多少年多少个月这样的一个时间范围。比如说我们想表达两年十个月这样的一个范围,怎么去表达呢?那就可以直接给定一个INTERVAL2杠十,然后year two months,所以这我们也就知道了,为什么前面啊,表示时间数值的这个必须要用一个string啊,啊,这样可以指明当前这个复合单位年到底是几个,月到底是几个。
12:22
这就是关于系统函数里的第一大类标量函数,它的使用都非常的简单啊,因为我们说它就类似于map嘛,一对一的一个转换,那与之对应呢,还有另外一大类就是所谓的聚合函数,它跟标量函数就不一样了啊,它不是一对一的转换,它是要把这个表里边的很多个行作为输入,然后聚合计算之后得到一个值,哎,所以我们说它就应该是一个多对一的转换,整体来看的话,可以对应着data API里面的reduce操作。那其实前面我们看到了啊,在CQ里边聚合操作其实是有很多种的,有分组聚合,窗口聚合,还有开窗聚合,不过呢,不管哪种聚合操作,在使用的时候,那其实调用的函数都是一样的,所以这里的这个聚合函数呢,是完全通用的,同样的聚合函数它实现固定的功能,在不同的场合里边呢,针对不同的数据,收集起来的数据去进行一个聚合操作就可以了。
13:24
啊,那一般这个标准CQ里面常见的聚合函数link CQ都是支持的,而且呢还在不断的扩展啊,为我们做这个流处理应用提供了更加强大的功能,所以这一部分其实是非常非常重要的啊,那一般常用的比如说像这个count返回横的数量啊,返回个数sum计算一个某个字段对应的这个求和的值啊,另外呢,还可以指定这个distinct的对数据进行一个去重。另外还有两个非常特殊的聚合操作,那就是rank和road number啊,那这两个聚合操作呢,它主要就是跟当前的排名情况有关啊,Rank直接就是返回当前值在一组数据当中的排名,而number呢,哎,那返回的就是对一组数已经做了排序之后,返回一个行号,整体来看的话,它俩起到的作用差不多。
14:16
那一般情况呢,它需要做排序,所以往往都用在over窗口里边啊,那之前我们介绍套喷的时候,Row number这样一个聚函数起到了非常关键的作用。这就是关于系统函数的一个简单介绍,当然我们知道啊,系统函数非常非常多,所以我们也没有必要把所有的系统函数都了解,都知道该怎么样去使用啊,那只有在具体应用的过程当中想要实现哪种需求了,这个时候我们到官网上再去做一个查询,使用对应的系统函数就可以了。
我来说两句