有谁知道如何在Hadoop中的两个数据集之间实现Natural-Join操作?
更具体地说,这就是我需要做的事情:
我有两组数据:
存储为(tile_number,point_id:point_info)的点信息,这是1:n键值对。这意味着对于每个tile_number,可能有几个point_id:point_info
存储为(tile_number,line_id:line_info)的行信息,这又是1:m键值对,对于每个tile_number,可能有多个line_id:line_info
< / LI> 醇>正如您所看到的,tile_numbers在两个数据集之间是相同的。现在我真正需要的是根据每个tile_number连接这两个数据集。换句话说,对于每个tile_number,我们有n个point_id:point_info和m line_id:line_info。我想要做的是将所有对point_id:point_info连接到每个tile_number的所有行line_id:line_info
为了澄清,这是一个例子:
对于点对:
(tile0, point0)
(tile0, point1)
(tile1, point1)
(tile1, point2)
对于线对:
(tile0, line0)
(tile0, line1)
(tile1, line2)
(tile1, line3)
我想要的是:
表示图块0:
(tile0, point0:line0)
(tile0, point0:line1)
(tile0, point1:line0)
(tile0, point1:line1)
瓦片1的:
(tile1, point1:line2)
(tile1, point1:line3)
(tile1, point2:line2)
(tile1, point2:line3)
答案 0 :(得分:8)
使用映射器将标题输出为键,将点/线输出为值。您必须区分点输出值和线输出值。例如,您可以使用特殊字符(即使二进制方法会更好)。
因此地图输出将类似于:
tile0, _point0
tile1, _point0
tile2, _point1
...
tileX, *lineL
tileY, *lineK
...
然后,在reducer中,您的输入将具有以下结构:
tileX, [*lineK, ... , _pointP, ...., *lineM, ..., _pointR]
你必须将这些值分开点和线,做一个交叉产品并输出每对交叉产品,如下所示:
tileX (lineK, pointP)
tileX (lineK, pointR)
...
如果您已经可以轻松区分点值和线值(取决于您的应用规格),则不需要特殊字符(*,_)
关于您在reducer中需要做的交叉产品: 首先遍历整个值List,将它们分成2个列表:
List<String> points;
List<String> lines;
然后使用2个嵌套for循环来执行交叉产品。 然后遍历结果列表并为每个元素输出:
tile(current key), element_of_the_resulting_cross_product_list
答案 1 :(得分:1)
所以基本上你在这里有两个选项。减少边连接或Map Side Join。
此处您的群组密钥是“平铺”。在单个减速器中,您将获得点对和线对的所有输出。但是您必须在阵列中缓存点对或线对。如果对(点或线)中的任何一对(非常大)都不适合单个组密钥(每个唯一磁贴)的临时数组内存,则此方法将不适合您。请记住您不必在内存中同时保存单组密钥(“磁贴”)的两个密钥对,一个就足够了。
如果单组密钥的两个密钥对都很大,那么你将不得不尝试map-side join。但它有一些特殊的要求。但是,您可以通过对两个数据运行相同数量的reducers的map / reduce作业进行一些预处理来满足这些要求。
答案 2 :(得分:0)
我发现这个有用
加入普通的Map Reduce或MultipleInputs
http://kickstarthadoop.blogspot.in/2011/09/joins-with-plain-map-reduce.html