00:00
好,那接下来呢,我们还要写一个自定义的UDTF函数,对吧?哎,这列函数比这个叫麻烦了,你想一下,有这TF函数叫一进多出,那肯定比这个麻烦,这是不是进来一个参数,我输出一次啊,对吧?一进一出啊,参数的个数无所谓对吧?参数个数我们今天说了啊,就是说那个一跟多跟参数的个数没关系了,是站在行的角度来说的,对吧?好,行,那接下来呢,我们来自定义函数当中再来一个啊,咱们UDT函数它呢要继承这个JA。UDPF函数,其实你关于udf函数好多都被过时了,就算这个东西啊,我给大家看一下,为什么我们不讲,因为它里面好像过时了,哎,比如这个没有过时呢,对吧?这个udf没有过时吗?来你看啊,我先给大家演示一下这个东西啊,虽然你看着它没有过时,但是它里面用的东西怎么样过时了,其实他现在用的sum那些函数啊,都是都是给过时的啊,就很奇怪他一直也不改啊,那我们现在UDTF肯定是记成那个什么。
01:08
UTF,然后alt加回车对吧,实现里面的方法好呃,它只有两个,一个process,一个呢close,这个毋庸置疑就是处理。输入什么输据的方法,Close是不是最后收尾的方法呀,对吧,就类似于假如说你中间用的IO流什么样子的,你在外面定义一个最后呢,在close方法里面给它关闭掉啊收尾方法,其实我们这里边呢,也没有那个内容啊,那我们要写一个什么样的一个uf呢?是这样子的,我们是不是有X explore这个UUDT,但是X explore它只能接收数组,对不对,对吧,我们自己写一个UDTF方程数,也是实现类似的扎列功能,我们让它输入字符串,以逗号分割的字符串,对吧?你给我输入逗号分割的字符串,我能给你实现加列功能,能懂这意思,也就是说这个函数啊,我们做一个解释啊,输入数据啊,大概呢,是这个样子的,叫hello,逗号对吧?啊,微博啊,什么Spark啊,当然是。
02:21
Have啊好,那我们输出呢,我们要变成这个样子,Hello,艾特微博,Have,这不是UDTF吗?对吧?而且注意它就是一个字符串啊,之前X比较麻烦一点是你要传字符,传的话你还必须得用一个什么Li,先把它切分成数组,对吧?然后再去用X导,那这个我们就更方便一点了,对吧?好,那我们要实现这个功能,呃,这里边呢,其实他让我们实现的是不是两个方法啊,还有一个方法最好也要实现一下,不是最好就一定要实现一下这个方法,还是这个什么初始化方法。
03:03
啊,还是初始化方法,那这个方法应该说他肯定有自己实现好的方法呀,那我们去看一下对吧,点开。找到它的初始化方法,它是不是还是调用重载的那个初始化方法,点它里边干什么,是直接抛异常对吧?所以呢,这个初始化方法我们最好还是干什么,自定义一下,自定义一下,但是问题来了,那这个东西呢,跟刚才返回值好像不太一样的,Object多了一个的结构体,因为你炸裂出来可以有多个。列啊多个列,所以说它这个集合啊,呃,那这块怎么写呢,刚才不教了大家方法了,是不是一般的遇到这种我们怎么办。点进去对吧,CTRL加H,看它的一个时间类,我们随便去挑一个,假如说哎,这不有XEXP吗?或者说杰森这些东西对于杰森做了处理,对吧,我们找一个找到它的初始化方法,我们找到它是什么返回值啊,它其实在中间也是做一些什么校验啊,也做一些校验工作,对吧?啊说至少得有两个参数啊,这不是抛异常吗?如果小于一是不是跟刚才做的是一样的,对吧?啊,那我们这个就不做校验了啊,我们直接把最终的反馈指令拿过来。
04:26
拿过来对吧?啊,从源码当中去获取我们所需要的东西啊,那现在呢,他要传两个参数,一个叫fair name。要一个叫菲的o is,那左边的o is不就它吗?对吧?好,那这两个我们直接alt加回车创建本地的变量,它是一个集合,那你会不会创建你一个是好了,对吧?OK,这边奥加回车创建本地的方法啊,本地的变量它还是一个集合,所以我们用一个好,那么这两个东西干什么用的呢?第一个它叫field的name字段名,哎,我们在用这个什么some或者说count,虽然我们没有取别名的时候,它是不是也会给一个。
05:27
来我们看一下的name,看新from这个叫business啊,哎,我们是哪个写错了啊,Bos少一个S对吧。呃,这个位置看的心,我们是不是没有曲别名啊,对吧,那也就是说它这个东西啊,是默认的名字。
06:01
啊,就默认给你一个列取的名字啊,每一个函数呢,都有它自己的一个名字啊,当然可以被别名所什么覆盖啊,所以所以说这个地方呢,你随便写一个就好了啊,随便写一个,这个叫下划线C1是吧,啊看C1啊,它叫这个名字,就是说它会有一个名字啊,这个呢是默认。输出啊,应该叫输出数据的默认列名啊,大家可以被别名覆盖啊,可以被别名覆盖,而这个东西刚才我们看到它里面放的是叫。Object inspector,这不就放刚才那么一长串的东西还记得对吧?这个是输出数据的类型啊,类型啊放在这里边,它这个集合呢,是因为它里边啊,可以炸出来多个列,就是说假如说我有一行数据,中间呢,既有有逗号分割的啊,中间又有冒号分割的,我可以炸出来两个不同的列啊,就是说我可以这样做啊,就现在呢,假如说有个hello,艾特硅谷吧,我把这个写一下。
07:14
假如说我或者在这写啊,就是说对于炸裂函数啊,我们现在看到的是它是不是只能炸出来一个列啊,对吧?哎,来我们做这个事,我们给大家看一下,嗯,Select。From这个TEST3这张表。啊三这张表对吧,那这个东西是不是数,这个东西是不是map呀,我们对它炸裂,你看一下啊select X pro,之前我们说了X pro里边是不是要接收数组或者说。Map对吧,那如果说是它的话,那你扎出来大家都知道之前我们好像是结过对吧,是这样子的一个列对吧?那如果说我们去炸裂它呢,两个列就炸裂函数呢,允许输出,不不光是可以输出多个行,还能输出什么多个列,那所以人家在定义的时候用的是什么?用的是集合,假如说你要多个列呢,只不过说我们在战列出来一个列的时候,集合当中放了一个元素而已呗。
08:21
对吧,啊,当然它可以是多个啊,可以多个是这个意思,这个放交验器的,好,那我们把这两个补充一下啊,非要的name点爱这个我们给什么名字,给what好了单词对吧?啊这出来一个一个单词,然后这个东西呢,叫非的O点这个是不是又是那一长串啊。那这个我们应该用string类型了吧,单词嘛,对吧?啊用词缀类型好,这是最终的返回值。这还是在定义什么,就是校验,当然你可以把这个输入参数做校验,我们没做校验了,校验的话,咱们是不是可以从这去找一找它里的校验啊,数据的什么长度啊等等这些东西都可以,对吧?更重要的呢,是定义列名,定义什么类型,然后呢,返回啊,跟udf是不是一样的,Udf刚才我们是不是定义了一个类型叫int。
09:18
返回数据类型脚印的对吧,这是初始化方法,然后接下来呢,我们处理输入数据,现在我们的输入数据是什么样子。是一个字符串对吧,那这个地方呢,我们设一个object对吧,所以这个这个东西啊,它没有进行国外的封装是吧?我们就可以取零直接干什么to string了,跟刚才不太一样了,对吧?这个还是第一步的好,这个呢是第一步取出输入啊数据,那接下来我们是不是要将这个东西按照逗号分割呀,对吧,第二步按照逗号分割字符串,那就音input的点什么,按照逗号分割得到一个我对吧啊,得到很多的一个单词,一个单词的一个数组,那么接下来。
10:26
一进多出,是不是对于每一个单词我们要写出去一次,就类似于像大家所写的map方法这种感觉,Map方法是不是用context这种方式写出的,对吧,那这一块呢,它里边也有一个写出方法啊,来到这来我们到这。它里边的写出方法呢,叫来看看这个也是把它写到了一个什么缓冲区里边,对吧?啊,收集器也写的缓冲区用的是forward啊,用的forward是这个意思,就是这个方法呢,就相当于是map当中的那个context.right对吧?你不是进来一行数据,按照逗号切分,然后用context.right调用很多次,每一个单词写出去一次嘛,对吧?一样的啊好,那么问题是我们前面定义的是不是集合呀,所以咱们写出数据的时候也得用什么用集合,但这里面集合我们需要定义很多吗?不需要,我们是会定义一个全局的集合,就类似于大家在写map任务,呃,把那个什么text的那个对象写在外面,然后去设置这个值,是不是一样道理啊,那我完全可以把集合写在外面,对吧?Private,然后。
11:44
放到是一个a list a list里边泛型放的是。放什么东西这类型,我们单词不就是类型吗?对吧?好这个叫奥啊叫它等于一个又一个,这个是输出数据的集合,好那么接下来呢,我们就便利数据是不是写出第三步写出对吧?好,那便利的话was点调用后循环就好了。
12:27
那这个word我们是不是应该把它放到output list里边,然后去写出是吧,写出的话是不是刚才我们说的用for,然后把list给它认识,这样对吗?大家想一下,这样写对吗?我们当前的集合是不是在外面定义的全局的一个集合呀,对吧?那第一条数据进来的时候是不是就放了几中,第二条数据又往里放,那你在写的时候是不是就写一二两条数据了,第三条又写1233条数据了,那结果就不对了,对吧?所以少了什么怎样的一个步骤清空对吧?哎,对了,清空集合也就在这块呢,我们在写的时候先要干什么?清空集合对吧?啊,因为你用的是集合嘛,点颗就好了,对吧?清一下,清一下之后呢,放进去,那结合当中就有一个数据对吧?给它写出去啊,给它写出去,当然如果说你炸出来是两个列,就类似于炸MAP2个列的话。
13:42
啊,那你及格当中就放两个数据呗,对吧?啊就这个意思啊,就放两个数据就好了啊,所以呢,它这个写法在这啊,就是这个写法呢,其实跟我们map是不是很像啊,对吧?Text说to string,然后spli,然后呢去写出,只不过说写法呢,之前map里边用context.right这块呢,用的是forward啊,它自己的框架有自己的写出的规则嘛,你按照它的规则来就好了,对吧。
我来说两句