要进行自连接,您可以遵循“减少端连接”模式。映射器将连接/外键作为键发出,将记录作为值发出。
因此,假设我们想要对以下数据的“城市”(中间列)进行自连接:
don,baltimore,12
jerry,boston,19
bob,baltimore,99
cameron,baltimore,13
james,seattle,1
peter,seattle,2
映射器将发出键->值对:
(baltimore -> don,12)
(boston -> jerry,19)
(baltimore -> bob,99)
(baltimore -> cameron,13)
(seattle -> james,1)
(seattle -> peter,2)
在减速器中,我们会得到:
(baltimore -> [(don,12), (bob,99), (cameron,13)])
(boston -> [(jerry,19)])
(seattle -> [(james,1), (peter,2)])
从这里,您可以执行内部连接逻辑(如果您愿意)。为此,您只需将每个项目与其他每个项目进行匹配即可。为此,请将数据加载到数组列表中,然后对项目执行 N x N 循环以相互比较。
意识到减少端连接的成本很高。如果您不过滤掉任何内容,它们会将几乎所有数据发送到减速器。另外,将数据加载到化简器的内存中时要小心——通过加载数组列表中的所有数据,您可能会在热连接键上耗尽堆。
上面的内容与典型的reduce-side join 有点不同。连接两个数据集时的想法是相同的:外键是键,记录是值。唯一的区别是这些值可能来自两个或更多数据集。您可以使用MultipleInputs http://hadoop.apache.org/common/docs/r1.0.3/api/org/apache/hadoop/mapreduce/lib/input/MultipleInputs.html让不同的映射器解析不同的输入集,然后让减速器从两者收集数据。
在没有任何约束的情况下,交叉产品是一场噩梦。 IE。,
select * from tablea, tableb;
有多种方法可以做到这一点。它们都不是特别有效。如果您想要这种类型的行为,请给我留言,我会花更多时间解释实现此目的的方法。
如果您能找出某种连接键(这是相似性的基本键),那么您的情况就会好得多。
我的书的插头:MapReduce 设计模式 http://shop.oreilly.com/product/0636920025122.do。它应该在几个月内发布,但如果您真的感兴趣,我可以通过电子邮件将有关连接的章节发送给您。