我想使用hadoop来处理非结构化CSV文件。这些文件是非结构化的,因为它们包含来自不同类型的多个不同行长度的数据值。此外,还有数百个这样的文件,它们的大小通常相对较大(>200Mb)。
每个文件的结构可以这样演示:
Book , ISBN , BookName , Authors , Edition
Book , 978-1934356081, Programming Ruby 1.9 , Dave Thomas, 1
Book , 978-0596158101, Programming Python , Mark Lutz , 4
...
BookPrice, ISBN , Store , Price
BookPrice, 978-1934356081, amazon.com , 30.0
BookPrice, 978-1934356081, barnesandnoble.com , 30.67
BookPrice, 978-0596158101, amazon.com , 39.55
BookPrice, 978-0596158101, barnesandnoble.com , 44.66
...
Book , ISBN , BookName , Authors , Edition
Book , 978-1449311520, Hadoop - The Definitive Guide, Tom White , 3
...
文件是自动生成的,我无法控制给定的结构。基本上,有一个标题行,后面跟着包含与标题匹配的值的数据行。行的类型可以通过第一个逗号分隔的单词来识别。因此,在该示例中,Book
行包含有关书籍的元数据(名称、isbn、作者、版本),BookPrice
包含不同销售点/供应商的书籍的各种价格。
我正在尝试了解如何使用Map/Reduce对数据执行一些聚合计算。按照这种方式对数据进行结构化会使人们更难理解在每个阶段提取什么key -> value
对。
例如,我想计算每本书的AVERAGE、MAX和MIN价格(可以按ISBN合并/分组)。我意识到我可以做一些预处理,将数据提取到有序的、单类型的CSV文件中,然后从那里开始工作(使用grep、python、awk等),但这将克服使用M/R+Hadoop的问题,并且需要大量额外的工作。
我曾想过使用多个地图阶段,但我对这一切都很陌生,不知道如何/从哪里开始。
如何为示例文件/查询实现这种M/R作业(在Java中)?谢谢
我遇到了一些类似的情况,并进行了以下设计:
我已经开发了使用OpenCSV解析器来实际分割记录的输入格式。然后我将MapWritable填充为一个值。每个映射包含一个带有"fieldName->field value"条目的记录
在你的情况下,我会让Key像枚举器一样,包含"价格记录"、"作者记录"等记录类型。
然后,在映射器中,您可以编写相对简单的代码,识别感兴趣的记录并聚合它们
一种更复杂但更有价值的方法是为Hive创建SerDe,它将文件映射到结构表中:记录类型(如上所述)和KeyValueMap列。(配置单元支持该列的映射类型)。然后,您就可以针对半结构化数据生成SQL了