问题:在访问日志中会出现会话中断但是用户未离开的情况,会产生两条或更多记录,但是这些记录都是一次访问的日志,希望可以合并记录;
期望结果:
user_name arrived_time leave_time A 00:00 00:23 A 00:23 00:40 A 00:40 00:50 A 04:00 04::23
user_name arrived_time leave_time A 00:00 00:50 A 04:00 04:23
可行性方案:
- 图计算解决
- 窗口函数解决
优缺点:
- 图计算思路比较清晰,就是传递起始时间到叶节点,但是技术实现起来要比写sql难度大,毕竟图计算不是人人都熟悉
- 窗口函数实现起来比较复杂,但是由于是使用sql可能对于我来说比较熟悉
下面就简单说下两种方案的实现思路:
首先说图计算
- 将每个用户赋予user_id 如果已经有了那就直接用就可以
- 将时间拼成int或者bigint类型与user_id组合成为图的节点id
- 边的起点与终点就是到达时间和离开时间
- 消息必须要有的是起始点的开始时间其他属性可以适当添加
- 迭代结束后将图的节点属性输出
窗口函数:
- 首先窗口函数需要处理当前行与上一条数据,按用户分区,按时间排序(到达时间),对比当前记录的到达时间与上一条数据的离开时间是否相同,如果相同打1的标签(也就是新增一列)否则填0
- 将以上结果再次使用窗口函数窗口中要处理当前行与下一行的数据若标签列的乘积为1则再次打delete的标签否则填F,被打伤delete标签的行表示这条数据既不是用户首次到达也不是最后离开的记录
- 将上述被打了delete标签的数据删除掉,剩下的数据就是到达和离开的两条或者正常的一条记录了
- 再次使用窗口函数,本次窗口函数需要处理的是当前记录和后一条记录,若标签列为0且后一条记录的标签列为1则将leave_time替换为后一条记录的leave_time
- 将标签为1的数据删除,得到最终结果
附上窗口函数的使用方法:hive窗口函数,spark窗口函数使用