1. 前言
本文將對Kettle6中常用步驟列拆分爲多行(英文原名:Split Field to Rows)。也就是說,將輸入數據行集中的某個列按照條件拆分爲多行。這種條件可以是簡單的一個分隔符,也可以指定正則表達式。
2. 說明
步驟的屬性對話框如下圖所示:
下面通過一個表格逐項解釋每一個對話框中字段的含義。
序號 |
名稱 |
含義 |
1 |
字段名稱 |
標識本步驟的名稱。 |
2 |
要拆分的字段 |
從輸入數據行集中,挑選需要拆分的字段。 |
3 |
分隔符 |
拆分字段時,使用的分隔符。簡單情況下,分隔符劃分的每一個字符串片段,都將成爲一個新行。 如果4選中,那麼這裏的分隔符實質是一個正則表達式。 |
4 |
分隔符是一個正則表達式 |
控制3的真實含義。如果選中,3就是正則表達式。否則,不管3中的字符串是何內容,Kettle只是將其當成一個分割文本的字符串。 |
5 |
新字段名 |
分割列後形成的新字段名稱。輸出數據行集將包含這個新的列,列的值爲分割後形成的字符串片段。 |
6 |
輸出中包含行號 |
輸出數據行集中,是否需要包含行號字段。如果需要,那麼應輸入這個行號字段的名稱。 |
7 |
對接收到的每一行重置行號 |
輸出數據行集中的行號,類似於一個序列,從1開始,每行增加1。如果選中7,那麼每一個輸入行集中的每一行,將獨享一個從1開始的序列;否則,所有輸入行集中的行共享一個序列。 舉例來說,假設輸入數據行集中有2行,第一行拆分爲3行,第二行拆分爲2行。如果選中7,那麼產生的行號是1 2 3 1 2;如果未選中7,那麼產生的行號是1 2 3 4 5。 |
3. 實戰
假設從輸入數據行集中拿到如下數據:
需要把其中所有市、區、縣的名稱得到,依次按行處理。
可以看出,來源數據實際上只有一行,但是想得到的結果是多行,這就需要用到列拆分爲多行步驟。步驟的具體設置可以參照文章開始的第一個圖,通過上述步驟,這一行被拆分爲以下行:
注意上圖,其中第一行爲空。其實這應屬Kettle6的一個bug。如果分割列的正則表達式正好滿足來源行的頭部,那麼分割結果中將產生一個空行!
如果要解決這個bug,可以往下閱讀附錄部分。
4. 附錄
解決第3部分實戰中第一個行數據爲空的bug,可以在類:
org.pentaho.di.trans.steps.splitfieldtorows.SplitFieldToRows
的方法splitField中增加以下代碼(117行後):
if(splitStrings.length>1&& StringUtil.isEmpty(splitStrings[0])){
String[] handledStrings = new String[splitStrings.length-1];
System.arraycopy(splitStrings, 1, handledStrings, 0, handledStrings.length);
splitStrings = handledStrings;
}
這樣可在輸出到目標數據行集前將第一個空行處理掉。