hive表结构例如以下:

create table pv_user_info(
session_id string,
user_id string,
url string,
starttime bigint
);

主要就是这几个字段实用。省略其它。

实现方式:userid和sessionid分组后并按时间降序排序,降序排序后。第一行就是该用户最后一次浏览的网页。最后一行是第一次浏览的网页,第一行的starttime和第二行的starttime相减就是第二行停留时间。

这里会有几个误差

用户最后一次浏览的网页时长:由于不知道用关闭浏览器的时间。所以没办法计算,就返回一个特定的值吧,我这里返回的是0。

跨天:任务是按天统计,还没有第二天的数据,所以不考虑跨天。

连续点开多个网页:按上面的实现方式就会有误差。这是没办法的。

按产生日志文件的结果看。仅仅能用这样的实现方式,除非专门写个js记录网页停留时长(不知是否可行),那么就不须要用hive了。

详细实现:

1.要实现行与行之间的比較或算加减法hive sql是实现不了的,仅仅有自己定义函数UDF

2.定义全局变量,存上次浏览时间。sessionid。userid

3.第一次调用evaluate方法上次浏览时间肯定是空的。也就是说是用户在这一天里最后一次浏览网页的时间,直接返回0即可了。

4.再次调用evaluate方法要推断是不是同上一次调用evaluate方法是不是同一个用户同一个会话。假设是的话就相减。

5.调用evaluate方法假设和上一次调用不是一个用户。说明这个网页是还有一个用户最后一次浏览网页的时间。直接返回0。

hiveUDF代码

import org.apache.hadoop.hive.ql.exec.UDF;

public class CalcUDF extends UDF {

	// 记录上一次訪问信息
private String[] lastLine = new String[2];; // 记录上次一次訪问时间
private Long lastTime = null; public Long evaluate(Long currentTime, String[] currentLine) {
if (lastTime == null) { lastTime = currentTime;
for (int i = 0; i < currentLine.length; i++) {
lastLine[i] = currentLine[i];
} return 0L;
} else {
// 同一个用户sessionId 和 userId 相等
if (currentLine[0].equals(lastLine[0])&& currentLine[1].equals(lastLine[1])) {
Long useTime = lastTime - currentTime; lastTime = currentTime; for (int i = 0; i < currentLine.length; i++) {
lastLine[i] = currentLine[i];
}
return useTime;
} else { // 还有一个用户
lastTime = currentTime;
for (int i = 0; i < currentLine.length; i++) {
lastLine[i] = currentLine[i];
}
return 0L;
}
}
}
}

将代码打成jar包。上传到/home/hadoop/test/

进入hive命令行,运行:

add jar /home/hadoop/test/hiveUDF.jar; // 加入jar包 

create temporary function calc as 'com.orange.hadoop.CalcUDF';    //创建函数

//最后运行hive sql

select session_id,user_id,url,starttime,
calc(starttime,user_id,session_id)
from
(select * from pv_user_info distribute by user_id,session_id sort by user_id,session_id ,starttime desc) t;

这是我的实现方式。有没有更好的解决方式?

hive计算网页停留时长的更多相关文章

  1. 使用Scala编写Spark程序求基站下移动用户停留时长TopN

    使用Scala编写Spark程序求基站下移动用户停留时长TopN 1. 需求:根据手机基站日志计算停留时长的TopN 我们的手机之所以能够实现移动通信,是因为在全国各地有许许多多的基站,只要手机一开机 ...

  2. js用img代替ajax js心跳 向服务器定时传送参数 主要计算用户在线时长

    html: <!doctype html><html><head><meta charset="utf-8"><title&g ...

  3. jave 计算音视频时长

    File source = new File("视频.mp4"); Encoder encoder = new Encoder(); try { MultimediaInfo in ...

  4. Fragment时长统计那些事

    注:本文同步发布于微信公众号:stringwu的互联网杂谈 frament时长统计那些事 页面停留时长作为应用统计的北极星指标里的重要指标之一,统计用户在某个页面的停留时长则变得很重要.而Fragme ...

  5. PHP根据秒计算持续时长

    /** * 计算持续时长 * * @param int $second 秒数 * @return string $duration 5天10小时43分钟40秒 */ function second2d ...

  6. jq计算总时长

    1: <style> .item { width: 500px; height: 50px; margin: 0 auto; text-align: center; font-size: ...

  7. js计算在线时长

    后台传来毫秒,前台转换成对应的时分秒 //在线时长 function longTime(seconds){ //总秒数 //seconds=seconds/1000; //得到小时 var hour ...

  8. 【Android端 APP 启动时长获取】启动时长获取方案及具体实施

    一.什么是启动时长? 1.启动时长一般包括三种场景,分别是:新装包的首次启动时长,冷启动时长.热启动时长 冷启动 和 热启动 : (1)冷启动:当启动应用时,后台没有该程序的进程,此时启动的话系统会分 ...

  9. js读写Cookie问题(Cookie存储时长、Cookie存储域)汇总

    在采集网站用户行为数据/使用js对用户行为做交互时,经常会使用到Cookie,了解Js Cookie的读写,以及一些细节,非常重要.   什么是Cookie 所谓Cookie,只是一条极为短小的信息, ...

随机推荐

  1. windows10家庭版 远程桌面报错

    windows10家庭版 远程桌面报错“要求的函数不受支持 ...”,Windows没有编辑组策略选项(gpedit.msc),所以无法按照微软提供的方法来修改组策略.所以我们需要修改注册表的方法来修 ...

  2. day13 函数模块之序列化 random 模块 os模块 sys模块 hashlib模块 collections模块

    json import json dic = {'k1':'v1','k2':'v2','k3':'v3'} str_dic = json.dumps(dic) #序列化:将一个字典转换成一个字符串 ...

  3. Java Thread.join()详解

    一.使用方式. 二.为什么要用join()方法 三.join方法的作用 join 四.用实例来理解 打印结果: 打印结果: 五.从源码看join()方法   一.使用方式. join是Thread类的 ...

  4. URAL1966 Cipher Message 3

    题目描述 题解: 能看出来的是,每一组数只能改最后一位,所以前$7$位动不了. 所以$KMP$跑一跑. 重点在于最后一位怎么搞. 如果$KMP$跑完了还没找到合适的位置,直接$puts("N ...

  5. RHEL6.5 DHCP服务器搭建

    RHEL6.5 DHCP服务器搭建: DHCP服务器是用来分配给其它客户端IP地址用的,在RHEL 6.5中DHCP服务器搭建方法如下: 第一步,通过yum安装dhcp服务: 命令:yum insta ...

  6. 使用Docker compose编排Laravel应用

    前言 Laravel官方开发环境推荐的是Homestead(其实就是一个封装好的Vagrant box),我感觉这个比较重,于是自己用Docker compose编排了一套开发环境,在这里分享下. 环 ...

  7. Dev Express中Dock panel的使用

    使用DockManager,添加DockPanel. 1,DockManager位于“导航和布局”分类中. 添加一个DockManager控件到窗体中以后,即是在当前窗体类中,添加一个DockMana ...

  8. scrapy_redis使用介绍

    scrapy_redis是一个基于redis的scrapy组件,通过它可以快速实现简单的分布式爬虫程序,该组件主要提供三大功能: (1)dupefilter——URL去重规则(被调度器使用) (2)s ...

  9. win7 如何将python加入环境变量

    我的电脑->右键属性->高级->系统变量 path里加上安装路径,比如 ";C:\Python26;" 请加分号附在其他path后面而不是直接覆盖.

  10. Python2和Python3共存安装robotframework

    1.下载Python2.Python3安装包 https://www.python.org/ 2.下载pip.tar.gz https://pypi.python.org/pypi/pip#downl ...