开发者学堂课程【2020版大数据实战项目之DMP广告系统(第六阶段):商圈库_功能_求差获取商圈】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/681/detail/11833
商圈库_功能_求差获取商圈
内容介绍:
一. 读取商圈表 取出经纬度
二. 取差集
三. 实现代码 获取商圈
接下来就去做第二个分支,但是在做第二个分支之前,再梳理一下当前的整个类的逻辑。
首先整个 business area,business runner 这样的一个类,它其中大致具有这样的一些内容,首先这个 odstable name 其实就是 O D S 的表明,area table name就是商圈表的名称。
有一个方法叫做 location togeohash,这个方法就是传一个 longitude 和 latitude ,生成一个 geohash ,它表示一个经纬度的范围。
那么接下来还有一个方法叫做 Fetch area 。这个 fetch area 就是给一个经纬度再去请求高德的这个api,请求好这个api以后拿一个 option,这个 option 直接进行转换,生成对应amp location对象拿到location对象取出其中的这个 business area 。它是一个list,再通过 map 把 name 拼起来,再把 mkstring 转成一个 string ,这时 fetch area 就已经把商圈信息转成东单逗号,西单这样的一种数据格式了。
一.读取商圈表 取出经纬度
接下来最终要在main方法来进行使用。第一步读取O D S和area商圈表,接下来注册了两个udf,就是刚才两个函数。这个注册完之后,到了第一个分支,说明这是第一次生成商圈表,这个商圈表它是empty的,也就是它并不存在,这时就直接取出O D S层表,通过O D S层表当中取出location和latitude,再出经度和纬度。
取出经度和纬度以后生成geohash,然后把列命名为geohash,再去生成这个商圈信息,把列命名为area,那么这就是整体上的逻辑。
二.取差集
那么接下来走到第二个分支里,可以发现 area option 是 is defined,这时它已经能够进行相应的取差级了,也就是说已经有这个商圈信息了,所以应该怎么办呢?现在主要的逻辑是什么?
O D S 中如果针对某个经纬度范围已经生成过商圈了,那么就不要再生成一次,所以如果要想做到这件事,步骤应该大致是怎么样的呢?大致有几个大步骤。
第一个大步骤要先去取差集,但是这个场景下没有办法直接取差集,因为O D S当中是没有商圈信息的,但是商圈库当中是有商圈信息的,所以它两个表的数据照不起来,只有 Key 一样,还想取差集,就可以进行 john,那如果要进行john,第一步还是要在这个 O D S 表中,投影出经纬度,最终生成geohash列和area这个列。
接下来第二步,就可以拿到根据O D S生成的这个数据,假设叫做 odswitharea 和area 进行 join。进行 join 时,应该怎么进行 join 呢?首先应该保留 O D S的数据。
那么就进行 join,如果 join 不到,就保留 O D S L的数据,那其实就是一个左外连接。那在 join 完以后,如果结果表中有数据的area为空,就可以从高德Api中获取数据。也就是说,如果 join 完了以后,其中某一列的area为空,必须从高德api获取数据。
因为它没有join到,说明这个odswith area当中的数据缺失的,就是没有进行商圈库统计的。
三.实现代码 获取商圈信息
第一步还是要先去 V a L 拿到 O D S 层表,其实就是 ods option.get。再接下来去拿到area的这张表,就是area option.get。为什么可以在这里直接get呢,因为前面已经判断了它是已经有值的,这样就可以拿到ods. Select。
那么这个 select,还是要 select 一个 exper,这个按照什么去select 呢?按照一个脚本来进行 select ,按照表达式来进行 select。再把这个 fetch 和 geohash的这个列的生成拷贝过来。其实在这个select exper 之前是不需要再进行一次这样的select的,因为可以直接取到 longitude和 latitude,并且select过以后这里面也只有两列,就是 geohash 和 area。
这样的一个数据集可以直接进行join,和谁 join 呢?和 area进行 join。那么和 area进行 join,应该在什么条件下来进行?
就可以输入 ods.colname,这个 ods 当中的 geohash 这一列,如果等于这个 area,olname 当中的 geohash,如果这两列相等就可以来进行 join,但是保留左边的数据还是保留右边的数据呢?应该保留这个 Ods 的数据,因为最终是要看到O D S 里面多了数据的话要对这个数据也生成商圈库的信息,所以是一个 left join。那么这时 left join 过了以后就可以继续向下进行。
前面可以生成 geohash,但是不应该直接 fetch area ,因为如果直接 fetch area,那么就会把整个的这个数集当中都生成area信息,所以这样做是完全不科学的。
可以这么做,这个地方 select exper 以后要去添加几列 ,longitude 和 latitude 还是需要的,因为后面要生成的时候要去使用。接下来去通过 with column,生成一个新的列,这个列就命名为 area,命名为area以后要去生成里面的数据,就可以直接使用lit。但是这个 lit 是一个 function 函数,要先在走到前面去导入这个function函数,那么就可以输入
import org.apache.spark.sql.functions._这个代码,把数倒进来,这个lit就不再报错了。
lit当中要传入一个值当这个列当中的默认值,那这个默认值希望是col。接下来就可以去area一个新的列,这个列就命名为area,其实这里as没有意义,已经命名为叫做area。这样就完成了。
已经添加一个新的列并且叫做area了,也join 过了, join 过了以后就要再进行一个filter或者进行一个 where ,那么这个 where 可能相对来说比较好用一些,就直接使用 where 。那就可以拿到area 当中的 colname。
如果是 colnames null ,那么这时就说明对应的这一列是没有数据的,没有数据就应该对其生成就是从高德当中获取到的结构化的一个地址信息,这样一步以后再进行相应的处理。
再进行一个 select ,那这个 select ,就可以 exper ,最终确定一下这个结果。第一点可以需要的就是这个 geohash ,这个 geohash 肯定需要。还需要一个操作就是要去 fetch area,那这个 fetch area 里面就需要一个 longitude 和 latitude。
这时就把其中的这个位置信息,结构化名字取到了,因为报黄线,所以往前退一格,然后写一个点,这样就不报黄线了。
差不多只需要这两列数据。以这里再 as 一下, as area。整个的这个数据的这个操作就完成了,到时候这个数据只需要给它 append 到 kudu 表当中,整个的功能就实现了。
那么这就是这一部分的内容,前面加上个 result 让它等于这个代码。接下来还是应该去测试一下 result 来进行一个 show,另一边的 result 也进行一个 show。
先去测第一个 show。那么第一个show如果没有问题,就把数据保存下来,保存完以后才能测第二个。所以先去进行第一个的 show,show完了以后就去运行这一段代码。
先点击这个小箭头去运行,
这时已经运行完毕了,但是出现了一个错误,这个错误是必须出现,是回避不了的。
这个错误说明它有一个类找不到,这个类叫做 scala xml meta data。这个应该是一个 json 的一个依赖,在 main 当中去导入对应的一个依赖库就可以了,这个依赖特别不好记,所以打开原来的代码来拷贝一个这样的依赖就可以了。scala long 下的scala xml 这个版本也是固定的,就必须要用这个版本。
接下来就进入到这个 Pom 文件当中啊,打开 project 打开 Pom 文件,在最前面的这个位置在 scar 后面,导入这样的一个xml,再去运行一下这段代码。这时就已经运行出结果来了,这个结果对应的第一列就是 geohash,然后第二列对应的是纬北路,北坦,水昌,解放大路,民康等等这样的一些内容。
那么这个章节也就先暂时告一段落,已经看到第一个逻辑判断是没有问题了,接下来在下一个视频当中确定第二个逻辑判断没有问题,然后去把数据落地到这个 kudu表当中。