在hadoop中处理行数据以添加缺少的列

时间:2013-08-20 19:12:36

标签: hadoop hive apache-pig

我有来自IIS的日志文件存储在hdfs中,但是由于webserver配置,一些日志没有所有列,或者它们以不同的顺序出现。我想生成具有公共模式的文件,以便我可以在它们上面定义一个Hive表。

好日志示例:

#Fields: date time s-ip cs-method cs-uri-stem useragent
2013-07-16 00:00:00 10.1.15.8 GET /common/viewFile/1232 Mozilla/5.0+Chrome/27.0.1453.116

缺少列的示例日志(缺少cs-method和useragent):

#Fields: date time s-ip cs-uri-stem 
2013-07-16 00:00:00 10.1.15.8 /common/viewFile/1232

需要将缺少列的日志映射到完整模式,如下所示:

#Fields: date time s-ip cs-method cs-uri-stem useragent
2013-07-16 00:00:00 10.1.15.8 null /common/viewFile/1232 null

错误日志可以启用任何列的组合,顺序不同。

如何根据日志文件中的Fields行将可用列映射到完整模式?

编辑: 通常我会通过将列模式定义为dict映射列名到索引来实现此目的。即:col ['date'] = 0 col ['time'] = 1等然后我会从文件中读取#Fields行并解析出已启用的列并生成标题dict映射头名称到文件中的列索引。然后,对于剩余的数据行,我通过索引知道它的标题,通过header = column name将其映射到我的列模式,并以正确的顺序生成新行,插入带有空数据的缺失列。我的问题是我不明白如何在hadoop中执行此操作,因为每个地图单独执行,因此如何与每个地图共享#Fields信息?

1 个答案:

答案 0 :(得分:1)

您可以使用this将标头应用于创建地图的列。从那里你可以使用UDF,如:

<强> myudf.py

#!/usr/bin/python

@outputSchema('newM:map[]')
def completemap(M):
    if M is None:
        return None
    to_add = ['A', 'D', 'F']
    for item in to_add:
        if item not in M:
            M[item] = None
    return M

@outputSchema('A:chararray, B:chararray, C:chararray, D:chararray, E:chararray, F:chararray')
def completemap_v2(M):
    if M is None:
        return (None,
                None,
                None,
                None,
                None,
                None)
    return (M.get('A', None),
            M.get('B', None),
            M.get('C', None),
            M.get('D', None),
            M.get('E', None),
            M.get('F', None))

将缺少的元组添加到地图中。

示例输入:

csv1.in             csv2.in
-------            ---------
A|B|C               D|E|F
Hello|This|is       PLEASE|WORK|FOO
FOO|BAR|BING        OR|EVERYTHING|WILL
BANG|BOSH           BE|FOR|NAUGHT

示例脚本:

A = LOAD 'tests/csv' USING myudfs.ExampleCSVLoader('\\|') AS (M:map[]); 
B = FOREACH A GENERATE FLATTEN(myudf.completemap_v2(M));

输出:

B: {null::A: chararray,null::B: chararray,null::C: chararray,null::D: chararray,null::E: chararray,null::F: chararray}
(,,,,,)
(,,,PLEASE,WORK,FOO)
(,,,OR,EVERYTHING,WILL)
(,,,BE,FOR,NAUGHT)
(,,,,,)
(Hello,This,is,,,)
(FOO,BAR,BING,,,)
(BANG,BOSH,,,,)