之前举过的案例:数据去重、数据排序、平均成绩都是在数据上进行一些简单的处理,为进一步的操作打基础。“单表关联”这个实例要求从给出的数据中寻找所关心的数据,它是对原始数据所包含信息的挖掘。下面进入这个实例。
问题描述
实例中给出 child-parent(孩子——父母)表,要求输出 grandchild-grandparent(孙子——爷奶)表。
样例输入如下所示: 样例输出如下所示:
家族树状关系谱:
设计思路
分析这个实例,显然需要进行单表连接,连接的是左表的 parent 列和右表的 child 列,且左表和右表是同一个表。
连接结果中除去连接的两列就是所需要的结果——“grandchild--grandparent”表。要用 MapReduce 解决这个实例, 首先应该考虑如何实现表的自连接;其次就是连接列的 设置;最后是结果的整理。
考虑到 MapReduce 的 shuffle 过程会将相同的 key 会连接在一起, 所以可以将 map 结果的 key 设置成待连接的列, 然后列中相同的值就自然会连接在一起了。 再与最开始的分析联系起来:
要连接的是左表的 parent 列和右表的 child 列,且左表和右表是同一个表,所以在 map 阶段将读入数据分割成 child 和 parent 之后,会将 parent 设置成 key,child 设置成 value 进行输出,并作为左表;再将同一对 child 和 parent 中的 child 设置成 key,parent 设置成 value 进行输出,作为右表。为了区分输出中的左右表,需要在输出的 value 中再加上左右表左右表的信息,比如在 value 的 String 最开始处加上字符 1 表示左表,加上字符 2 表示右表。这样在 map 的结果中就形成了左表和右表,然后在 shuffle 过程中完成连接。reduce 接收到连接的结果,其中每个 key 的 value-list 就包含了“grandchild--grandparent”关系。取出每个 key 的 value-list 进行解析,将左表中的 child 放入一个数组,右表中的 parent 放入一个数组,然后对两个数组求笛卡尔积就是最后的结果了。