00:00
好,接下来我们继续这一部分data loader代码的实现,呃,大家会想到在这个data loader里边我们已经定义好了一些样例类,接下来我们做什么事情呢?那是不是在里边应该就,呃,大家想到这就是一个单例对象了,那里边是不是就来一个main函数就可以了呀,然后直接执行对不对?那里边执行的过程应该是什么样的流程呢?是不是一开始我们先创建一个Spark config对象啊,对吧?然后大家会想到这个我们就直接先敲一下吧,Spark conig,呃,这个我们就先等于none啊,大家先把这个流程先梳理一下,然后接下来是不是创建Spark session对不对,嗯,Spark。
01:00
As。呃,那么当然这个里边是不是就有了这个Spark context啊,就有了SC对不对,我们接下来要做一些操作的时候,呃,去读取数据的时候,是不是可以在SC里边会有一个呃,Text file的一个一个这个方法我们可以直接去从文件里面读取啊,呃,好,然后这里边我们还是定义出来,我们就叫Spark吧,简写啊,等于呢。有了这两个之后,接下来是不是就可以去加载数据了,那大家会想到我们就从文件里边读取出来,是不是应该是一个RDD啊,等于now哇,呃,我们还有RA对吧?RDD等于那同样还有tag r DD先都把它等于那然后先把这个梳理出来,最后我们再来统一来做,呃,那接下来我们如果要是已经把这个数据都已经拿过来之后,可能要对数据进行一些预处理,对吧?啊,这里我们先放在这里啊,数据预处理,然后我们是不是应该把对应呃,就是想要存的数据保存到mango里边去啊,对吧?将数据保存到mon。
02:30
GODB,这里我们定义一个一个函数吧,Store data in mon go DB这里我们先定义这么一个,那当然了,后边大家会想到还应该把数据保存到ES对不对?ES,那么这个同样定义一个store data in ES,就这样两个方法完成之后是不是就完事了啊,我们就把Spark session关闭就可以了啊,当然可以,这个stop,好,这就是我们整个的一个基本的框架代码的一个流程,对不对?呃,在这个过程啊,当然大家看着这个报错不太爽的话,我们下面当然要把它定义出来对不对,DeFine store这个啊。
03:33
先给一个空的实现store data ES实现出来啊,这里大家如果看着这个报错不爽的话,我们先把它注掉,最后再把它放开就可以了,对不对啊,这就是我们整个的这个主体流程,那然后大家会想到我们如果要是想要在这个过程当中做一些操作的话,大家可能想到这个前面这些都是常规操作,对不对啊,这些其实都是常规操作,那可能就是后面这个保存到mango和保存到ES这两个函数比较复杂一些,对不对啊,那这一部分为了我们把这个代码规范化一些,对于mango和ES的操作,我们是不是应该把它相关的配置还是包装成样例类,然后再在后面给它把一些配置信息传入进去啊啊,所以这是我们的一个基本想法啊,这里。
04:25
把呃,Mongo和ES的配置封装成样例类啊,那大家看一下,就是我们这里边到底是需要哪些东西呢?大家看mongo配置里边其实需要就一个uri,还有一个DB,指定这两个是不是就可以了,ES的配置里边可能会多一些http hosts对吧,Transport hosts,然后index name啊,这几个都是需要的,对吧,我这里边就不详细敲了,大家可以就是还是手敲一下,我把这个直接copy过来好好有了这样的两个这个样例类之后,那那大家可能如果要是觉得这个还有点怀疑的话,那我们可以看一下这个东西到底是什么,对吧,有。
05:25
包爱,那这其实这个不用写了,对吧,这是猫mongo DB的连接对不对?DB,那这个就是对应的那个数据库下面这个,呃,那这个htv host这是什么呢。这是就是HTTP主机列表对不对,就是我们要连接的ES的主机列表,列表它是用什么分割,是不是逗号分割的对吧,逗号分割,然后这个列表对不对,这个是大家知道transport列表是是用什么来做什么的,我们一般情况是不是指定的那个端口会不一样,就是前面的http host,这是不是都是9200对吧,一般是,那它就是相当于是接收HTTP请求的那个端口,也就是我们的客户端要想去连接到这个ES服务器的时候,我们发送请求发送到9200端口对不对,那这里面的transport host它的端口是不是往往就不是9200啊啊9300对不对,那它是用来做什么的呢?那是用来集群。
06:50
彼此之间做内部的这个数据传输用的对不对啊,9300,所以这个也是逗号风格,我们就不写了啊,那index这个是什么呢?对,是不是就是我们需要操作的索引啊好,那最后c name这个是什么?是集群名称对吧?默认应该是什么?
07:18
是配置名是吗?啊对,配置里边当然会会会给这个名字,如果大家要是什么都不改的话,比方说像我这里,我直接就一个单节点直接起起来,大家忘记这个的话,我们先先那个看一眼啊,我这里边到,呃,我这里边有一个WIN10的自带的一个Linux子系统,大家可以看到,我可以在这里边去做一些操作,我进入到ES里边来,呃,B下面是不是直接就可以执行这个elastic search这个命令,对吧?直接就可以把它提起来啊,当然大家如果不想看它的那些操作信息的话,可以后面加杠D啊。
08:00
那我们这里边如果起起来之后,是不是应该可以在9200端口直接访问啊,对吧。现在可能还没有没有提起来看一眼啊,嗯,好,嗯,大家看到报了一个错,呃,Warning这个应该没关系啊。等一下啊。还没有起起来,现在这个状态稍微有点慢。好,下面还在起对吧。呃,大家会想到就是其实在我们一开始连接的这个过程当中,应该就是诶这个这里no such file exception。哦,这个应该没关系,大家看到这个system vm下面它要去有这样的一个check对吧,那这里边这个,呃,大家看这个9300这里已经提起来了对吧?这里1270.0.19200提起来了,对吧?诶大家看这里是不是访问已经可以访问到了,我们一般看到这个页面的时候,就代表这个ES已经提起来了,对吧?大家看这里边是不是就有一个在哪呢?Cster name对不对?默认的是什么?对,就叫elas search对吧?啊,所以这个是默认的名,一般是叫这个我们这里我这里提起来,如果不改的话,就还用这个就完了,对不对?大家如果要是自己改过配置文件的话,那注意这里边给的就不是这个elastic search了,还是给自己定义好的那个啊好,这是这一部分样例类的一个定义,那大家看我们这里是先把样例类定义出来了,那接下来我们具体用到的这些配置连接是不是还。
09:48
哎,应该有一些常数,这个参数应该要写进去啊,那这里边我们是不是就在main里边,呃,定义一个常量就可以啊,是不是可以定义一个conig这样的常量,那它当然就应该是一个map了,对吧?啊,所以我们定义这样的一个map主要要什么样的字段呢?这里边我还是直接到文档里面给大家看一眼吧,啊大家看就是这里面定义好的,那我们Spark这里边是不是也需要定义Spark cause这个字段啊啊,大家会记得啊,那这里边的local芯,Local芯代表什么?就是本地要要起这个多线程对不对,然后就是尽可能的多,对吧,有几个用几个这样的一个方式,那接下来mongo uri,这是不是我们定义的UI啊啊,这个mongo DB大家看我这里边定义的就是local host的27017默认提起来写的数据库是不是recommend这个数据库啊啊,然后下面。
10:48
那当然DB也定义好了,Recommend,然后接下来htp host是不是local host9200,我这里是单节点transport host9300对不对,然后ES index,我指定的这个,指定的这一个索引名称叫做recommend啊,这个也没问题,对不对啊,最后还有一个customername定义成什么啊,就是默认的electric search,好,我把这个就直接copy过来。
11:15
好,放在这里。呃,有了这些内容之后,接下来我们是不是就是按部就班就可以一步一步来做这些操作了啊,大家回忆一下这个sparknig,我们一般是要new一个new一个Spark config好。这好慢啊,然后后边是不是可以去set master对不对?那这个master我们给什么呢?是不是从config里边去取对,取这个spark.course就可以了,对吧?然后后边我们还可以set APP name对不对?这都是常规操作啊,一般我们给的是不是就是当前的这个类名啊,对,Data loader啊,这样是不是就可以了,这是基本的一个配置项,然后这个创建SPA session的时候,我们是不是要去Spark session,对,然后是不是要点啊,点builder对不对?然后点config,是不是要把我们前面的Spark config要传进去啊,然后是不是点get or create对吧?如果有的话直接用,没有的话是不是创建一个啊啊,这是大家比较习惯的这种写法,应该都没什么问题。
12:39
呃,然后接下来大家注意一下,我们接下来加载数据之后,可能还是希望把它转成这个是RDD,对吧,可能还希望把它做一些操作,比方说转成DF之类的,然后再用Spark Spark CQ,把它写到mango里边就会比较方便,对不对,那这里要想要去这个呃,转成DF,想要去用相关的一些东西,我们是不是还得引入一个一个包啊,大家记得吗?诶,这个这个是不是要import一个对Spark点对in input这个影视包对不对啊,下划线把所有的东西都引入对不对,我们先把这个东西引入,然后接下来大家会想到这个我是不是应该可以调用啊,这个SC里边的text file这个这个方法去把从文件里边读取数据,然后呃,转换成RDD对不对,加载成RD。
13:40
那这里边大家就要注意了,我是不是先得定义出来,你那个文件在哪啊,对吧,那这个东西我们同样这是常量,我是不是应该在这里定义出来。呃,那大家会看到我这里边比方说定义一个叫做movie data pass它的路径对不对,那这个路径从哪找呢?是不是就是我们这个路径啊,已经放在这个resources路径下面了,对不对?哎,我们可以把这个copy一下,它的pass直接是不是就可以复制在这里啊,大家看,直接复制过来之后,它已经做了这个反斜杠的转移,这是Windows下的这个呃路径。
14:27
应该是这样的一个表达,对不对啊,大家看这个就没什么问题啊,当然同样的我是不是还可以定义rating data pass。大家会看到我这里边是不是就是把movies改成rating,哎,Ratings就可以了呀,其实目录他们都一样,对不对,我就不不再去重新复制这个东西了,呃,当然了,就是还应该定义一个tag data pass,对吧。
15:12
我们把它复制过来,这里边它是不是叫tag.csv啊,呃,这是我们定义好的这个路径的常量,然后接下来我们是不是就可以在下面的这一步去调用这个方法了,Movie r DD应该等于什么呢?是不是Spark,这里边是不是大家看有这个CQ contact,是不是还有Spark contact contact对吧?我们这个上下文SC对象,然后可以调用它里边是不是有一个text file方法啊,呃,那大家想这里边我们传入的是什么?是不是movie data pass啊,啊,先把它传进来,然后我们可能希望把它转成,就是做一些基本的操作,把它转成DF,对不对,Data frame,那大家想一下怎么把它转成data frame呢?Movie df应该等于什么呢?大家想到这个读来。
16:12
之后的数据是什么呀。是不是大家看是不是这么一长串,这个没有分割之前的数据啊,对吧,是这么一长串数据,那所以我们这里边是不是得按照这个分隔符把它每一个字段拿出来,然后利用我们定义好的样例类,是不是把它做一个包装,最后再转成df data frame,是不是就顺理成章,哎,最后就可以把它存到王里了,这就是我们基本的一个想法,所以是不是就要movie r DD,是不是要做一个map操作啊,呃,大家应该能想到接下来这个操作做什么啊,那对于它里边的每一个item。我们都去做一个操作,什么操作呢?我们是不是应该做一个切分啊,对,所以我们定一个attribute啊这样的一个变量,然后它等于什么呢?保存它切分开得到的所有的字段对不对?那大家会想到这里边我们要定义一个切割符对不对,那我们这里边切割符是什么?对上间号,但是大家要注意上间号在大家想这里边我们一般传入的是一个正则对不对?在正则的这个表达里边,上间号是不是需要做转移啊,啊,因为本身在正则里边,上间号表示开始的那个表示对吧?所以这里是不是得做转移。
17:46
但是正则里边是不是还有另外一个问题,反斜杠是不是也得转移啊?对,所以大家习惯这种写法,对不对?转两次前面这个转移表示我要把后面这个反斜杠转移对不对?所以两个反斜杠是不是代表一个反斜杠啊?然后一个反斜杠再加上间号,是不是表示把上上键号又可以转移啊,代表一个上键号对不对啊?所以是双重的转移,大家之前应该见过这样的一些表达,所以我们这里就不去做这些详细的分析了,那接下来我们是不是把它包成一个movie这样的case class,然后返回就可以了啊,大家会想到我这里边拿到的是不是attribute的零,是不是就应该是mid啊?我这里边切割出来的,切割出来的第一个元素就应该是mid,对不对,好,那么。
18:41
呃,如果是这个元素的话,我是不是应该把它转成int啊,对,Mid是唯一的一个int,剩下的全是string对不对?这个SP拿出来的都是对吧?别的就不用转了,呃,但是大家会想到可能会需要做一个什么处理呢?点tri,这是这是什么意思?对,是不是可以把就是首尾的这个空格空白字符去掉对吧,做一个标准的转换,呃,当然了,大家会想到剩下的所有的这些内容是不是都一样啊,好,那我就直接复制一下,大家数一下啊,0123456789,应该到九就可以了,对不对?好,现在他也不报错了。
19:31
我们把每一项都改过来,这就对应到了我们已经定义好的movie数据这个case class里边的每一个字段,对吧,三。二好。呃,那我们把它,呃这样一一最后一行数据,这就相当于这个返回值对不对,把每一个item是不是就转成了这样的一个movie数据类型啊,那做完之后。
20:02
这个map完之后,是不是我们还应该做一个操作啊,是不是可以把它转成对data frame对吧?To df这样就可以了,那我们做了这样的一串操作之后,大家发现后边的这个rating和tag是不是都一样啊?啊,这个操作应该完全一样对不对?spark.spark context text file里边这个就是rating。Data pass对吧?呃,然后接下来是不是也应该有类似的这样这样一串操作啊啊,这个我就不再去展开讲讲了,只不过这里我们的reading大家去看它的分隔符就不是上键号了,是不是变成了逗号啊,逗号的话在这个正则里边是不是就不需要再去做转移了,我们是不是直接去分隔就可以了啊,另外这个tag跟它是一样的,我就直接从这个。
21:01
我们的文档里面把它copy过来就可以了啊,大家看是不是就是这样一个操作。定义一个DRADF,好把它做一个操作,那同样这里的tag操作完全一致,对吧?啊,这个我就不写了。做完这些操作之后,那大家会看到,呃,当然这里的这个数据预处理,大家可以认为这已经做完了,对不对?呃,对于我们这个保存到mango而言就做完了,保存到ES的话可能还会有一点不一样,我们把这个数据处理放在这里吧。
我来说两句