本文介绍 路径分析函数 的使用场景,和函数的基本用法。
路径分析函数业务场景:选定一段时间范围,分析此时间范围内用户行为路径。
使用 pathSplit 生成每个用户所有的路径组合成的数组。
pathSplit(session_time, level)(timestamp, event, prop)
输入参数:
session_time
:路径分析的时间窗口,单位和timestamp
保持一致,下例中为 600 秒,也即只计算首个event 发生后 10 分钟内形成的路径;level
:路径深度,超过 x 个节点截断路径;timestamp
:时间戳 所在列,需要先转换成时间戳,再转换成 Uint64 格式;event
:事件列,仅支持数值类型,需要通过 multiIf 显式指定;如下例中的:multiIf(EventName = 'E0001', 1, EventName = 'E0002', 2, EventName = 'E0003', 3, 0) AS e
prop
:属性列,没有时传 ''
占位;输出参数(中间结果):
返回二维数组:[(e1, p1), (e2, p2), (e1, p2)]
event
列中 multiif
定义的事件编号prop
使用 array join 将单个用户单行包含所有路径的二维数组展开成多行单个路径。
使用 pathCount 统计所有用户的路径转化情况。
pathCount(y, x)(path, cnt1, cnt2)
pathCount 返回界面展示需要的数据,x 表示横向的路径深度(如上图为 4),
前端展示需要的数据其实就是每个浅蓝色方块代表的node,和浅蓝色方块之间的变edge,都是由pathCount输出
y
:纵向单层展示深度,如上图中黄色圈的部分,即 y = 5;x
:横向路径深度,超过 x 个节点截断路径,如上图中 x = 4;path
:pathSplit
的返回 path 列(需通过 arrayJoin 展开);cnt1
:路径权重1,通常直接传 1 就行,用于计算路径 去重后的次数;cnt2
:路径权重2,通常传pathSplit
子查询里的 count()
求出的 cnt ,用来求路径 不去重的总次数。返回格式:
node_index
:格式为:(event, prop)
,事件节点展示。
event
为事件的下标编号,若 之前 pathSplit 时 event 填写 multiIf(EventName = 'E0001', 1, EventName = 'E0002', 2, EventName = 'E0004', 3, 0),则此时返回 1 对应 'E0001' ,2对应 'E0002',3对应 'E0004';prop
为 pathSplit 传入的 prop。nodes
:二维数组。表示每个节点在各层级(level,下标从 0 开始)出现的去重次数、次数,格式为:(level, node_index, cnt1, cnt2)
。
(level, from_node_index, to_node_index, cnt1, cnt2)
指定一个用户 Visitor = 964049 来说明。
该示例为 2022/6/1-2022/6/2 中,发生 'E0001', 'E0002', 'E0004' 事件的路径数据,展示发生事件后 10 分钟内的页面信息,展示的页面路径深度为 3 层。
首先先通过 pathSplit 计算中间结果:
SELECT Visitor,pathSplit(600, 3) (toUInt64(toUnixTimestamp(LOG.EventTime)), multiIf(EventName = 'E0001', 1, EventName = 'E0002', 2, EventName = 'E0004', 3, 0) AS e, '') AS path FROM LOG WHERE (EventTime >= '2022-06-01 00:00:00') AND (EventTime < '2022-06-02 00:00:00') AND (EventName IN ('E0001', 'E0002', 'E0004')) and Visitor = 964049 GROUP BY Visitor --返回: ┌─Visitor─┬─path────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ │ 964049 │ [[(1,''),(2,''),(3,'')],[(1,'')],[(1,''),(2,''),(3,'')],[(1,''),(2,''),(2,'')],[(1,'')],[(1,'')],[(1,'')],[(1,''),(3,''),(3,'')],[(1,''),(2,''),(3,'')],[(1,''),(1,''),(3,'')],[(1,'')],[(1,''),(2,''),(3,'')],[(1,'')],[(1,''),(2,''),(2,'')]] │ └─────────┴─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
再通过arrayJoin 把单行的path 返回的二维数组表示的多条path展开成多行单条path,计算每一条path出现的次数
SELECT path AS path, count() AS cnt FROM (SELECT arrayJoin(pathSplit(600, 3)(toUInt64(toUnixTimestamp(LOG.EventTime)), multiIf(EventName = 'E0001', 1, EventName = 'E0002', 2, EventName = 'E0004', 3, 0) AS e, '')) AS path FROM LOG WHERE (EventTime >= '2022-06-01 00:00:00') AND (EventTime < '2022-06-02 00:00:00') AND (EventName IN ('E0001', 'E0002', 'E0004')) and Visitor = 964049 GROUP BY Visitor) GROUP BY path --返回 ┌─path───────────────────┬─cnt─┐ │ [(1,'')] │ 6 │ │ [(1,''),(1,''),(3,'')] │ 1 │ │ [(1,''),(2,''),(3,'')] │ 4 │ │ [(1,''),(2,''),(2,'')] │ 2 │ │ [(1,''),(3,''),(3,'')] │ 1 │ └────────────────────────┴─────┘
再通过 pathCount 计算出最终的 3*3 结果(路径深度为 3,同时每层至多展示的节点为 3 个):
SELECT pathCount(3, 3) (path, 1, cnt) FROM (SELECT path AS path, count() AS cnt FROM (SELECT arrayJoin(pathSplit(600, 3)(toUInt64(toUnixTimestamp(LOG.EventTime)), multiIf(EventName = 'E0001', 1, EventName = 'E0002', 2, EventName = 'E0004', 3, 0) AS e, '')) AS path FROM LOG WHERE (EventTime >= '2022-06-01 00:00:00') AND (EventTime < '2022-06-02 00:00:00') AND (EventName IN ('E0001', 'E0002', 'E0004')) and Visitor = 964049 GROUP BY Visitor) GROUP BY path ) --返回 ┌─pathCount(5, 3)(path, 1, cnt)─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐ │ ([(1,''),(3,''),(2,'')], [[0,0,5,14],[1,0,1,1],[1,1,1,1],[1,2,2,6],[2,1,3,6],[2,2,1,2]], [[0,0,0,1,1],[0,0,1,1,1],[0,0,65535,1,6],[0,0,2,2,6],[1,2,2,1,2],[1,1,1,1,1],[1,0,1,1,1],[1,2,1,1,4]]) │ └───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
结果为:
node_index
:[(1,''),(3,''),(2,'')],表示事件编号映射为 0->1(E0001),1->3(E0004),2->2(E0002)
nodes
:[[0,0,5,14],[1,0,1,1],[1,1,1,1],[1,2,2,6],[2,1,3,6],[2,2,1,2]]
edge:[0,0,0,1,1],[0,0,1,1,1],[0,0,65535,1,6],[0,0,2,2,6],[1,2,2,1,2],[1,1,1,1,1],[1,0,1,1,1],[1,2,1,1,4]
可以将结果信息补充为页面路径分析,如