如何在 Pig 中合并地图
How to Merge Maps in Pig
我是 Pig 的新手,请多多包涵。我有两个具有相同模式的数据源:属性映射。我知道某些属性会有一个可识别的重叠属性。例如
记录 A:
{"Name":{"First":"Foo", "Last":"Bar"}, "FavoriteFoods":{["Oranges", "Pizza"]}}
记录 B:
{"Name":{"First":"Foo", "Last":"Bar"}, "FavoriteFoods":{["Buffalo Wings"]}}
我想合并 Name
上的记录,这样:
合并:
{"Name":{"First":"Foo", "Last":"Bar"}, "FavoriteFoods":{["Oranges", "Pizza", "Buffalo Wings"]}}
UNION
、UNION ONSCHEMA
、JOIN
不是这样操作的。是否有一种方法可以在 Pig 中执行此操作,还是必须在 UDF 中执行此操作?
类似于:
A = LOAD 'fileA.json' USING JsonLoader AS infoMap:map[];
B = LOAD 'fileB.json' USING JsonLoader AS infoMap:map[];
merged = MERGE_ON infoMap#Name, A, B;
即使是稍微复杂的数据翻译,Pig 本身也很笨。我觉得你需要两种 UDF 来完成你的任务。第一个 UDF 需要接受一个映射并创建它的唯一字符串表示。它可能就像地图的哈希字符串表示(我们称之为 getHashFromMap())。该字符串将用于连接两个关系。第二个 UDF 将接受两个地图和 return 一个合并的地图(我们称之为 mergeMaps())。您的脚本将如下所示:
A = LOAD 'fileA.json' USING JsonLoader AS infoMapA:map[];
B = LOAD 'fileB.json' USING JsonLoader AS infoMapB:map[];
A2 = FOREACH A GENERATE *, getHashFromMap(infoMapA#'Name') AS joinKey;
B2 = FOREACH B GENERATE *, getHashFromMap(infoMapB#'Name') AS joinKey;
AB = JOIN A2 BY joinKey, B2 BY joinKey;
merged = FOREACH AB GENERATE *, mergeMaps(infoMapA, infoMapB) AS mergedMap;
这里我假设你要合并的属性是一张地图。如果这可能会有所不同,那么您的第一个 UDF 将需要变得更加通用。它的主要目的是获取属性的唯一字符串表示形式,以便可以在该属性上连接数据集。
我是 Pig 的新手,请多多包涵。我有两个具有相同模式的数据源:属性映射。我知道某些属性会有一个可识别的重叠属性。例如
记录 A:
{"Name":{"First":"Foo", "Last":"Bar"}, "FavoriteFoods":{["Oranges", "Pizza"]}}
记录 B:
{"Name":{"First":"Foo", "Last":"Bar"}, "FavoriteFoods":{["Buffalo Wings"]}}
我想合并 Name
上的记录,这样:
合并:
{"Name":{"First":"Foo", "Last":"Bar"}, "FavoriteFoods":{["Oranges", "Pizza", "Buffalo Wings"]}}
UNION
、UNION ONSCHEMA
、JOIN
不是这样操作的。是否有一种方法可以在 Pig 中执行此操作,还是必须在 UDF 中执行此操作?
类似于:
A = LOAD 'fileA.json' USING JsonLoader AS infoMap:map[];
B = LOAD 'fileB.json' USING JsonLoader AS infoMap:map[];
merged = MERGE_ON infoMap#Name, A, B;
即使是稍微复杂的数据翻译,Pig 本身也很笨。我觉得你需要两种 UDF 来完成你的任务。第一个 UDF 需要接受一个映射并创建它的唯一字符串表示。它可能就像地图的哈希字符串表示(我们称之为 getHashFromMap())。该字符串将用于连接两个关系。第二个 UDF 将接受两个地图和 return 一个合并的地图(我们称之为 mergeMaps())。您的脚本将如下所示:
A = LOAD 'fileA.json' USING JsonLoader AS infoMapA:map[];
B = LOAD 'fileB.json' USING JsonLoader AS infoMapB:map[];
A2 = FOREACH A GENERATE *, getHashFromMap(infoMapA#'Name') AS joinKey;
B2 = FOREACH B GENERATE *, getHashFromMap(infoMapB#'Name') AS joinKey;
AB = JOIN A2 BY joinKey, B2 BY joinKey;
merged = FOREACH AB GENERATE *, mergeMaps(infoMapA, infoMapB) AS mergedMap;
这里我假设你要合并的属性是一张地图。如果这可能会有所不同,那么您的第一个 UDF 将需要变得更加通用。它的主要目的是获取属性的唯一字符串表示形式,以便可以在该属性上连接数据集。