6

假设我跟踪用户在网站上进行的“事件”,事件可以是:

  1. 浏览主页
  2. 将商品添加到购物车
  3. 查看
  4. 已支付订单

现在,这些事件中的每一个都存储在一个数据库中,例如:

session_id event_name created_date ..

所以现在我想构建一个报告来显示一个特定的漏斗,我将定义如下:

Step#1   event_n
Step#2   event_n2
Step#3   event_n3

所以这个特定的漏斗有 3 个步骤,每个步骤都与任何事件相关联。

鉴于我拥有的上述数据,我现在如何为此构建报告?

注意:只是想清楚一点,我希望能够创建我定义的任何渠道,并能够为其创建报​​告。

我能想到的最基本的方法是:

  1. 获取数据库中每个步骤的所有事件
  2. 第 1 步将是,x% 的人执行 event_n
  3. 现在我将不得不查询也执行了步骤#1 的步骤#2 的数据,并显示 %
  4. 与#3 相同,但对于步骤#3 具有步骤#2 的条件

我很好奇这些在线服务如何在托管的 Saas 环境中显示这些类型的报告。map-reduce 是否以某种方式使这变得更容易?

4

3 回答 3

7

首先给出答案,使用标准 SQL,给定您的假设:有一个表 EVENTS 具有简单的布局:

EVENTS
-----------------------------
SESION_ID , EVENT_NAME , TMST

要获取在某个时间执行步骤#1 的会话:

-- QUERY 1
SELECT SESSION_ID,MIN(TMST) FROM EVENTS WHERE EVENT_NAME='event1' GROUP BY SESSION_ID;

在这里,我假设 event1 可以在每个会话中发生不止一次。结果是在某个时间展示 event1 的唯一会话列表。

为了获得 step2 和 step3,我可以这样做:

-- QUERY 2
SELECT SESSION_ID,MIN(TMST) FROM EVENTS WHERE EVENT_NAME='event2' GROUP BY SESSION_ID;
-- QUERY 3
SELECT SESSION_ID,MIN(TMST) FROM EVENTS WHERE EVENT_NAME='event3' GROUP BY SESSION_ID;

现在,您要选择按顺序执行 step1、step2 和 step3 的会话。更准确地说,您需要计算执行第 1 步的会话数,然后计算执行第 2 步的会话数,然后计算执行第 3 步的会话数。基本上,我们只需要将上述 3 个查询与左连接结合起来,就可以列出进入漏斗的会话以及它们执行的步骤:

-- FUNNEL FOR S1/S2/S3
SELECT 
  SESSION_ID, 
  Q1.TMST IS NOT NULL AS PERFORMED_STEP1,
  Q2.TMST IS NOT NULL AS PERFORMED_STEP2,
  Q3.TMST IS NOT NULL AS PERFORMED_STEP3
FROM
  -- QUERY 1
  (SELECT SESSION_ID,MIN(TMST) FROM EVENTS WHERE EVENT_NAME='event1' GROUP BY SESSION_ID) AS Q1,
LEFT JOIN
  -- QUERY 2
  (SELECT SESSION_ID,MIN(TMST) FROM EVENTS WHERE EVENT_NAME='event2' GROUP BY SESSION_ID) AS Q2,
LEFT JOIN
  -- QUERY 3
  (SELECT SESSION_ID,MIN(TMST) FROM EVENTS WHERE EVENT_NAME='event2' GROUP BY SESSION_ID) AS Q3
-- Q2 & Q3
ON Q2.SESSION_ID=Q3.SESSION_ID AND Q2.TMST<Q3.TMST
-- Q1 & Q2
ON Q1.SESSION_ID=Q2.SESSION_ID AND Q1.TMST<Q2.TMST

结果是在第 1 步进入渠道的唯一会话列表,并且可能已继续到第 2 步和第 3 步......例如:

SESSION_ID_1,TRUE,TRUE,TRUE
SESSION_ID_2,TRUE,TRUE,FALSE
SESSION_ID_3,TRUE,FALSE,FALSE
...

现在我们只需要计算一些统计数据,例如:

SELECT
  STEP1_COUNT,
  STEP1_COUNT-STEP2_COUNT AS EXIT_AFTER_STEP1,
  STEP2_COUNT*100.0/STEP1_COUNT AS PERCENTAGE_TO_STEP2,
  STEP2_COUNT-STEP3_COUNT AS EXIT_AFTER_STEP2,
  STEP3_COUNT*100.0/STEP2_COUNT AS PERCENTAGE_TO_STEP3,
  STEP3_COUNT*100.0/STEP1_COUNT AS COMPLETION_RATE
FROM
(-- QUERY TO COUNT session at each step
  SELECT
    SUM(CASE WHEN PERFORMED_STEP1 THEN 1 ELSE 0 END) AS STEP1_COUNT,
    SUM(CASE WHEN PERFORMED_STEP2 THEN 1 ELSE 0 END) AS STEP2_COUNT,
    SUM(CASE WHEN PERFORMED_STEP3 THEN 1 ELSE 0 END) AS STEP3_COUNT
  FROM
    [... insert the funnel query here ...]
) AS COMPUTE_STEPS

等等瞧!

现在进行讨论。第一点,鉴于您采用“设置”(或功能)思维方式而不是“程序”方法,结果非常简单。不要将数据库可视化为具有列和行的固定表的集合......这就是它的实现方式,但它不是您与之交互的方式。都是套装,你可以按照你需要的方式安排套装!

第二点,如果您使用的是 MPP 数据库,查询将自动优化为并行运行。您甚至不需要对查询进行不同的编程,使用 map-reduce 或其他任何东西......我在我的测试数据集上运行了相同的查询,其中包含超过 1 亿个事件,并在几秒钟内获得结果。

最后但并非最不重要的一点是,查询打开了无限的可能性。只需按推荐人、关键字、登陆页面、用户信息对结果进行分组,并分析哪个提供了最佳转化率!

于 2013-12-04T11:12:18.080 回答
2

您考虑这一点的方式的核心问题是您正在考虑 SQL/表类型模型。每个事件都是一个记录。NoSQL 技术的优点之一(您对此有所了解)是您可以自然地将记录存储为每个记录一个会话。以基于会话的方式存储数据后,您可以编写一个例程来检查该会话是否符合该模式。不需要做连接或任何事情,只需在会话中的事务列表上循环。这就是半结构化数据的力量。

如果您将会话存储在一起怎么办?然后,您所要做的就是遍历每个会话并查看它是否匹配。

在我看来,这是 HBase 的一个很棒的用例。

使用 HBase,您将会话 ID 存储为行键,然后将每个事件存储为值,并将时间戳作为列限定符。这给您留下的是按会话 ID 分组在一起的数据,然后按时间排序。

好的,所以现在您想弄清楚有多少会话执行了行为 1、2、3。您在此数据上运行 MapReduce 作业。MapReduce 作业将为每个行键/值对提供一个会话。在数据上编写一个循环以检查它是否与模式匹配。如果它确实计数+ 1,如果不是,则不要。


在不使用 HBase 的情况下,您可以使用 MapReduce 对静止的无组织数据进行会话。按会话 ID 分组,然后在 reducer 中,您将与该会话关联的所有事件组合在一起。现在,您基本上处于使用 HBase 的位置,您可以在 reducer 中编写一个检查模式的方法。


如果您没有大量可笑的数据,HBase 可能会过大。在这种情况下,任何可以分层存储数据的数据库都会很好。MongoDB、Cassandra、Redis 都会浮现在脑海中,各有优缺点。

于 2012-05-13T04:54:42.797 回答
1

我最近发布了一个开源 Hive UDF 来做到这一点:hive-funnel-udf

用于此类漏斗分析任务非常简单,您只需编写 Hive,无需编写自定义 Java MapReduce 代码。

不过,这仅在您使用 Hive/Hadoop 存储和查询数据时才有效。

于 2016-05-16T22:14:23.030 回答