我想使用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
行包含有关图书(name,isbn,author,edition)的元数据,而BookPrice
包含不同商店/供应商的图书的各种价格。
我正在尝试了解如何使用Map / Reduce对数据执行一些聚合计算。以这种方式构建数据使得理解在每个阶段中提取的key -> value
对更加困难。
例如,我想计算每本书的 AVERAGE , MAX 和 MIN 价格(可以加入/分组ISBN)。我意识到我可以做一些预处理来将数据提取到有序的单一类型的CSV文件并从那里开始工作(使用grep,python,awk等),但这将打败使用M / R + Hadoop的重点,并将需要大量额外的工作。
我考虑过使用多个地图阶段,但我对所有这些都很新,并且不确定如何/从哪里开始。
如何为示例文件/查询实现此类M / R作业(使用Java)?感谢。
答案 0 :(得分:3)
我遇到了类似的情况并做了以下设计:
我开发了使用OpenCSV解析器实际拆分记录的输入格式。然后
我将MapWritable填充为值。每个地图包含一个带有“fieldName-> field value”条目的记录。
在你的情况下,我会使Key像枚举器一样包含记录类型,如“价格记录”,“作者记录”等。
然后在您的映射器中,您可以编写相对简单的代码,该代码将识别感兴趣的记录并将其聚合。
更复杂但更有价值的方法是为Hive创建SerDe,它将文件映射到结构表:记录类型(如上所述)和KeyValueMap列。 (列的Hive支持地图类型)。然后,您就可以针对半结构化数据制作SQL。