2012-05-12 68 views
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. 現在我將要查詢的步驟#2誰也執行步驟1中的數據,並顯示%
  4. 同#3但步驟3與步驟#條件2

我很好奇這些在線服務如何在託管的Saas環境中顯示這些類型的報告。某種程度上,map-reduce是否使這更容易?

+0

那麼你可以在減速器中獲得每個會話ID的所有事件,如果你認爲這使得它更容易。 –

回答

2

您對此的思考方式的核心問題是您正在考慮SQL /表類型模型。每個事件都是一個記錄。 NoSQL技術的好處之一就是你可以自然地將記錄存儲爲每個記錄一個會話。一旦以基於會話的方式存儲數據,就可以編寫一個例程來檢查會話是否符合模式。無需進行連接或任何操作,只需在會話中的事務列表上循環即可。這就是半結構化數據的力量。

如果您將會話存儲在一起,該怎麼辦?然後,你所要做的就是遍歷每個會話並查看它是否匹配。

在我看來,這是HBase的一個奇妙的用例。

使用HBase,您可以將會話ID存儲爲行鍵,然後將每個事件存儲爲具有時間戳作爲列限定符的值。這些留給你的是按會話ID分組在一起的數據,然後按時間排序。

好吧,現在你想知道會話的百分比是什麼時候執行的行爲1,然後是2,然後是3.你對這些數據運行MapReduce作業。MapReduce作業將爲每行鍵/值對提供一個會話。在數據上寫一個循環來檢查它是否與模式匹配。如果它計數+1,否則不。


沒有全力以赴與HBase的,你可以使用MapReduce的休息時sessionize您的無組織的數據。按會話ID分組,然後在縮減器中將所有與該會話關聯的事件分組在一起。現在,您基本上已經在使用HBase,您可以在Reducer中編寫一個方法來檢查該模式。


如果您沒有可觀的數據量,HBase可能會矯枉過正。任何可以分層存儲數據的數據庫都適用於這種情況。 MongoDB,Cassandra,Redis都浮現在腦海中,各有優缺點。

+0

不知道我是否清楚,但我想讓用戶能夠定義渠道(每步的步驟和匹配事件),並且能夠查看歷史數據的報告。我想這意味着我將不得不運行批處理作業來將舊數據拖入給定的數據存儲區/結構中嗎?這個權利沒有神奇的方式嗎? – Blankman

+0

我剛剛在hbase上閱讀,我喜歡如何以這種分組方式存儲相關數據等。我如何做類似mongodb的事情? (hbase目前對我來說可能太多了) – Blankman

+0

是的,你必須編寫某種過程才能將它們集合在一起,或者如果你正在使用存儲這樣的數據的數據存儲,你可以修改記錄。如果你在做用戶,而不是會話,只需由用戶分組而不是會話ID。 –

7

首先答案,使用標準的SQL,因爲你的假設:

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的唯一會話列表。

爲了得到第二步第三步和,我可以做相同的:

-- 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; 

現在,你要選擇進行第一步,第二步和第三步的會議 - 按照這個順序。 更準確地說,您需要對執行步驟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 

結果是誰在第一步進入渠道的唯一會話列表,並可能繼續第二步第三步和...例如:

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 

等voilà!

現在進行討論。 第一點,結果是非常簡單的,因爲你採取「集」(或功能)的思維方式,而不是「程序性」的方法。不要將數據庫可視化爲包含列和行的固定表的集合......這是如何實現的,但它不是與它進行交互的方式。這是所有的設置,你可以按照你需要的方式來安排這些設置!

第二點,如果您正在使用MPP數據庫,查詢將自動優化爲並行運行。您甚至不需要以不同的方式編寫查詢,使用map-reduce或其他任何方法......我在測試數據集上運行了超過1億次事件的相同查詢,並在幾秒鐘內獲得結果。

最後但並非最不重要的是,查詢打開無限的可能性。只需根據引用者的結果,關鍵字,登陸頁面,用戶信息和分析結果進行分組,這些信息提供了最佳轉換率!

+0

我認爲這個查詢可能有問題,例如,如果我想知道誰做了:E1,E2,E3和我有一個與E2,E1,E2,E3會話我相信上述查詢將失敗(因爲它只考慮首次發生事件) – shaylevi2

+0

實際上並非如此。初始查詢中唯一的約束是E1 E2 => E3,但這需要計數首先在會話中的事件(可以很容易地通過窗口函數完成) – SergeFantino

0

我最近發佈了一個開源的蜂巢UDF做到這一點:hive-funnel-udf

這是非常簡單易用這種漏斗分析的任務,你可以只寫蜂巢,無需編寫自定義的Java的MapReduce代碼。

這隻有在您使用Hive/Hadoop存儲和查詢數據時纔有效。

+2

請不要發佈[重複答案](// meta.stackexchange.com/a/211726/206345)。相反,考慮其他可以幫助未來用戶找到他們需要的答案的行動,如鏈接文章中所述。 – Mogsdad