加入Mapreduce/Hadoop中的两个数据集

rez*_*eza 10 distributed hadoop join mapreduce

有谁知道如何在Hadoop中的两个数据集之间实现Natural-Join操作?

更具体地说,这就是我需要做的事情:

我有两组数据:

  1. 存储为(tile_number,point_id:point_info)的点信息,这是1:n键值对.这意味着对于每个tile_number,可能有几个point_id:point_info

  2. 存储为(tile_number,line_id:line_info)的行信息,这也是1:m键值对,并且对于每个tile_number,可能存在多个line_id:line_info

如您所见,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)
Run Code Online (Sandbox Code Playgroud)

对于线对:

(tile0, line0)
(tile0, line1)
(tile1, line2)
(tile1, line3)
Run Code Online (Sandbox Code Playgroud)

我想要的是如下:

对于瓦片0:

 (tile0, point0:line0)
 (tile0, point0:line1)
 (tile0, point1:line0)
 (tile0, point1:line1)
Run Code Online (Sandbox Code Playgroud)

对于瓷砖1:

 (tile1, point1:line2)
 (tile1, point1:line3)
 (tile1, point2:line2)
 (tile1, point2:line3)
Run Code Online (Sandbox Code Playgroud)

Raz*_*van 8

使用映射器将标题输出为键,将点/线输出为值.您必须区分点输出值和线输出值.例如,您可以使用特殊字符(即使二进制方法会更好).

所以地图输出将是这样的:

 tile0, _point0
 tile1, _point0
 tile2, _point1 
 ...
 tileX, *lineL
 tileY, *lineK
 ...
Run Code Online (Sandbox Code Playgroud)

然后,在reducer中,您的输入将具有以下结构:

 tileX, [*lineK, ... , _pointP, ...., *lineM, ..., _pointR]
Run Code Online (Sandbox Code Playgroud)

并且你必须将值分开点和线,做一个交叉产品并输出每对交叉产品,如下所示:

tileX (lineK, pointP)
tileX (lineK, pointR)
...
Run Code Online (Sandbox Code Playgroud)

如果您已经可以轻松区分点值和线值(取决于您的应用规格),则不需要特殊字符(*,_)

关于您在reducer中必须执行的交叉产品:首先遍历整个值List,将它们分成2个列表:

 List<String> points;
 List<String> lines;
Run Code Online (Sandbox Code Playgroud)

然后使用2个嵌套for循环来执行交叉产品.然后遍历结果列表并为每个元素输出:

tile(current key), element_of_the_resulting_cross_product_list
Run Code Online (Sandbox Code Playgroud)

  • 很棒,但这只有在你可以将整点/线放入内存以便将它们存储在两个提到的列表中时才有效.我担心在我的大型数据集中并非如此:( (4认同)