powercenter與kettle的排序取前n條記錄的比較


ETL這個詞對於從事BI職位的coder來說,相信並不陌生,今天的故事就從ETL的兩個工具powercenter與kettle說起。最近的1年多,由於各種原因,leader要求ETL這塊需要換一個工具。原來的powercenter被拋棄了,我們迎來了更加開源的kettle。原本主要從事於BI前端開發cognos工作的我也由於人手不足而被安排了一些ETL的改造任務,不管怎么來說,是繁瑣的工作也好或者是各種不同的問題,或者說是一種真心的疲憊。對於Leader我還是心存感激的,雖然平時也會有不少的抱怨。抱怨他的方式和大家的報酬一直得不到提升。因為最起碼從一個出發點來說,我學到了更多的東西,對於我這個少不更事的年輕人(二十四五歲,還算年輕吧)來說。好了言歸正傳,故事開始了。

需求:每天取不同店鋪交易額topN的商品交易額清單。

part1:原ETL的模型powercenter中的Mapping,如圖所示,在對所有指標分組聚合統計之后運用了Rank組件。

1.1:需要設置 rank的ports 屬性。里面就是上一步輸入的字段名稱。I-O—W-R 設置輸入輸出。此處最重要的就是設置R字段就是根據什么字段rank,這里勾上相應字段。接着如下圖:

1.2:設置rank后取的top記錄數 number of ranks 為3 則代表取每個group by 的top3,至於是升序或者是降序就是這里的頂部或者是底部了,設置top/bottom處為top即可,取Rank后的最大值向下。

總結:Powercenter中一個rank組件就解決了每天取top n條記錄的問題。

part2:kettle中如何實現這個問題呢?kettle中沒有rank組件。最終還是找到了解決的方法。

2.1:測試數據准備工作

-- 創建表
CREATE TABLE `tmallorder` (
  `datekey` INT(11) NOT NULL,-- 日期
  `storename` VARCHAR(50) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL, -- 店鋪名稱
  `goodsname` VARCHAR(50) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL, -- 商品名稱
  `goodsmoney` DECIMAL(20,4) DEFAULT NULL -- 銷售額
) ENGINE=INNODB DEFAULT CHARSET=utf8
-- 插入測試數據
INSERT INTO tmallorder(datekey,storename,goodsname,goodsmoney)
VALUES(20121111,'GXG旗艦店','GXG黑色呢絨大衣20121111G1',985231455.80)
INSERT INTO tmallorder(datekey,storename,goodsname,goodsmoney)
VALUES(20121111,'GXG旗艦店','GXG黑色呢絨大衣20121111G2',882373145.48)
INSERT INTO tmallorder(datekey,storename,goodsname,goodsmoney)
VALUES(20121111,'太平鳥旗艦店','太平鳥黑色呢絨大衣20121111T1',100025863.80)
INSERT INTO tmallorder(datekey,storename,goodsname,goodsmoney)
VALUES(20121111,'太平鳥旗艦店','太平鳥黑色呢絨大衣20121111T3',1126988817.48)
INSERT INTO tmallorder(datekey,storename,goodsname,goodsmoney)
VALUES(20121112,'GXG旗艦店','GXG黑色呢絨大衣20121111G1',2585231455.80)
INSERT INTO tmallorder(datekey,storename,goodsname,goodsmoney)
VALUES(20121112,'GXG旗艦店','GXG黑色呢絨大衣20121111G2',1585231455.80)
INSERT INTO tmallorder(datekey,storename,goodsname,goodsmoney)
VALUES(20121112,'太平鳥旗艦店','太平鳥黑色呢絨大衣20121111T1',300025863.80)
INSERT INTO tmallorder(datekey,storename,goodsname,goodsmoney)
VALUES(20121112,'太平鳥旗艦店','太平鳥黑色呢絨大衣20121111T2',170025863.80)

--最終的統計結果

日期          店鋪          商品名稱                              銷售額

20121111 GXG旗艦店 GXG黑色呢絨大衣20121111G1 985231455.8000
20121111 GXG旗艦店 GXG黑色呢絨大衣20121111G2 882373145.4800
20121111 太平鳥旗艦店 太平鳥黑色呢絨大衣20121111T1 100025863.8000
20121111 太平鳥旗艦店 太平鳥黑色呢絨大衣20121111T2 126988817.4800
20121111 太平鳥旗艦店 太平鳥黑色呢絨大衣20121111T3 1126988817.4800
20121112 GXG旗艦店 GXG黑色呢絨大衣20121111G1 2585231455.8000
20121112 GXG旗艦店 GXG黑色呢絨大衣20121111G2 1585231455.8000
20121112 太平鳥旗艦店 太平鳥黑色呢絨大衣20121111T1 300025863.8000
20121112 太平鳥旗艦店 太平鳥黑色呢絨大衣20121111T2 170025863.8000

2.2: 針對所有記錄排序取top n,不分組取top n

組件:sortrows+js

 2.2.1:

tmallorder就是測試表數據的一個輸出,sort rows 就是先針對記錄做一個排序,針對業務需求選擇是降序或者是升序,本例是取交易額大的所以排序指標是降序

排序字段為1個 交易額 ASC 為N即為降序排序。

2.2.2:

trans_Status = CONTINUE_TRANSFORMATION;
if(getProcessCount("r")>3) {
 trans_Status = SKIP_TRANSFORMATION;
}

SKIP_TRANSFORMATION , ERROR_TRANSFORMATION, CONTINUE_TRANSFORMATION是TRANSFORMATION已經預先定義好的靜態常量,不可更改。 作用是   過濾記錄行,控制轉換流程

例如:

trans_Status = CONTINUE_TRANSFORMATION

if (field.getString()==’123’) trans_Status = SKIP_TRANSFORMATION

getProcessCount("")方法在kettle是一個特殊的函數,含義和參數解釋spoon官方解釋:

// Returns a number with the current processed Rows.
// The type is changable.
//
// Usage:
// getProcessCount(var);
// 1: String - The Pentaho/Kettle Type:
// u - Lines Update
// i - Lines Insert
// w - Lines Write
// r - Lines Read
// o - Lines Output

JS后面的操作就是輸出處理后的數據了,我們可以看一下結果,如下圖。

在TEST的所有結果集里面取交易額top3記錄,我們看前面的表數據可以看出處理結果是正確的。

2.3: 針對所有記錄排序取top n,分組取top n 即在每天都取出top N

組件:sort rows+group by+Filter rows

2.3.1:因為是分組排序取top n,所以在分組之前排序的時候除了top n的標准字段金額之外,就是還要加上要分組的字段,如下圖:

goodsmoney就是top的標准按照金額最大取top 分組字段為datekey日期。

 

2.3.2:說到分組排序就要說分組了 這里我們就用到了我們日常經常使用的group by組件如下圖,打鈎的地方勾上。Add line number處給一個字段,名字自定

此處我設置的是rownunber,分組字段就是分組取top的字段比如每天,每個店鋪都可以。rownumber 會作為下一步的一個新增字段。

2.3.3:最后一步就是要用到過濾(Filter rows)上一步的rownumber其實就是分組排序后的每一個排名字段。我們取top3,

即為rownumber<4的所有數據

如下圖:

最終結果為:

和測試表結果對比后,我們可以發現11號和12號兩天的數據分別取top3是正確的。

2.4: 針對kettle分組排序取topn 的總結:

        其實規則都一樣,如果再往下擴展,取每天每個店鋪的top2我們就可以在sort rows 和group by 中添加指標即可,過濾的操作不變,就是topn 中N的值。

        取每天每個店鋪的top2:具體的就不再多說了,看步驟:

step1:    top指標還是交易額字段,group by 為日期 店鋪

 

 step2:group by 為日期 店鋪 添加排序標示

 

step3:取top2  rownumber<3

step 4:預覽處理結果:

和表中數據對比后可發現,11和12號兩天中,GXG和太平鳥兩個店鋪銷售額前2的商品數據是正確的。

 總結:無論是哪一種ETL ,工具其實都是有它的優點和缺點的。利用好他們的優點,想辦法解決他們的缺點,會給我們的工作帶來輕松和愉快,謝謝大家。

 

 

 

              

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2026 CODEPRJ.COM