用户行为分析系列实践 1 - 常规分组统计

目标任务

用户事件表T结构和部分数据示例如下:

Time UserID EventType
2022/6/1 10:20 1072755 Search
2022/6/1 12:12 1078030 Browse
2022/6/1 12:36 1005093 Submit
2022/6/1 13:21 1048655 Login
2022/6/1 14:46 1037824 Logout
2022/6/1 15:19 1049626 AddtoCart
2022/6/1 16:00 1009296 Submit
2022/6/1 16:39 1070713 Browse
2022/6/1 17:40 1090884 Search

T表字段说明:

字段名 数据类型 字段含义
Time 日期时间 事件发生的时间戳,精确到毫秒
UserID 整数 用户ID
EventType 字符串 事件类型

计算任务:

统计指定时间段内每种事件类型下的发生次数和发生过该事件的去重用户数

实践技能

1、 使用二进制文件存储替代数据库存储

2、 遍历中使用并行

示例代码

1、使用二进制文件转储数据库的数据

存量数据:从数据库中读出,写入集文件:


A
1 =connect("demo").cursor@x("select * from T")
2 =file("T.btx").export@b(A1)

A1 连接数据库,读取T表的数据,产生游标,@x选项表示读完后自动关闭数据库连接

A2 A1中的数据写入T.btx集文件中,用@b表示写成二进制文件。

增量数据:如果有新数据要追加到已经生成的集文件中,可以在SQL中用过滤条件筛选出来,用@a选项把数据追加到集文件里。

用时间戳来识别增量数据,每天0点以后,把前一天的增量数据追加到集文件里:


A
1 =connect("demo").cursor@x("select * from T where Time>=? && Time<?",date(now()-1), date(now()))
2 =file("T.btx").export@ba(A1)

A1 通过过滤条件筛选出前一天的数据,产生游标

A2 A1中的数据通过游标读出追加到T.btx集文件中,@a表示追加,无此选项则是重写

2、针对集文件做分组汇总

设统计时间段为2022315日到2022616日:


A
1 =file("T.btx").cursor@mb()
2 >start=date("2022-03-15","yyyy-MM-dd"),end=date("2022-06-16","yyyy-MM-dd")
3 =A1.select(Time<=end && Time>=start).groups(EventType; count(1):Num, icount(UserID):iNum)

A1 对集文件"T.btx"产生游标,@m表示多路游标,用于并行计算,缺省的并行数在集算器的raqsoftconfig.xml中设置,也可以直接写成f.cursor@m(n),这里n表示并行数。一般来说并行数不要超过机器的CPU核数,否则可能更慢。

A2 产生start,end两个变量,用于对时间戳进行过滤,实际使用时这俩变量通过参数传进来

A3 A1中的游标进行过滤和分组汇总,分组字段是EventTypecount(1)是简单计数,icount(UserID)是统计UserID不重复的个数。这里强调一点,不管对游标进行多少次操作,比如多次过滤、排序、分组等等,最后执行的时候都是一次性执行的,即只会取一次数遍历一次,就算出最终结果。

运行结果:

EventType Num iNum
AddtoCart 1845674 175476
Browse 3578901 348791
Login 4033000 393400
Logout 4033000 393400
Search 2947931 257539
Submit 867345 83375