使用基于标题记录的Spark HiveContext记录拆分

时间:2017-08-23 09:23:02

标签: apache-spark-sql

我有一个像下面这样的文件,其中包含从4个不同文件合并到源系统的单个文件中的数据。

NEWFILE =是数据的分隔符。例如,NEWFILE = STUDENT行之后和NEWFILE = SUBJECT行之后的所有数据都属于STUDENT文件。问题是我们没有任何模式来分隔每个文件的记录。此外,源系统无法将文件分成4个文件。

我需要加载这个单个输入文件,并根据记录的标题分隔记录。

我在Hive中使用了以下逻辑但是当我尝试将其转换为Spark作业时,我收到错误,因为“block__offset__inside__file”未知火花。我试图在spark中找到“block__offset__inside__file”的替代方案,但似乎没有替代JIRA链接https://issues.apache.org/jira/browse/SPARK-8006

我处于这种情况,我只能使用HiveContext / SQLContext在Spark中使用Hive查询进行此转换。

我想检查在Spark SQL中转换下面的hive查询是否可行。

如果在Spark SQL中不可能,那么我如何在Spark中应用类似的逻辑,因为spark转换是并行和分布式的。我认为我们不能将累加器用于行#identification ..

在Hive中使用SQL 选择测试场            ,headerno            ,row_number()结束             (                 按fileno分区                 由headerno命令             )作为记录编号

from(select testfield                    ,block__offset__inside__file为headerno

               ,count(case when testfield like 'NEWFILE=%' then 1 end) over
                (
                    partition by    input__file__name
                    order by        block__offset__inside__file
                ) as fileno


        from    test
        ) inner

文件内容数据如下所示

NEWFILE=STUDENT
100 XYZ
101 ABC
102 DEF
NEWFILE=SUBJECT
1 ENGLISH
2 MATHS
NEWFILE=TEACHERS
110 AAAAAAAA
111  BBBBBBB
222  CCCCCCC
333  DDDDDD
NEWFILE=CLASSES
1 CLASS-1
2 CLASS-2

1 个答案:

答案 0 :(得分:0)

如果这是一次性摄取,而你只有大约1000万 我可能会选择这样一个简单的bash脚本:

while read LINE || [[ -n $LINE ]]; do
  if [[ $LINE =~ NEWFILE= ]]; then
    FILENAME=${LINE##NEWFILE=}
    echo $FILENAME
  else
    echo $LINE >> $FILENAME 
  fi
done < file

file是您文件的名称。

对于大数据来说太多了!

如果必须定期进行此操作,我可能会要求负责此输出格式的开发人员将其更改为更标准且易于以分布式方式解析的内容,例如每个类别一个文件或Avro。