pig中map的分组键值

Posted

技术标签:

【中文标题】pig中map的分组键值【英文标题】:Group key value of map in pig 【发布时间】:2012-09-18 12:21:21 【问题描述】:

我是 pigscript 的新手。说,我们有一个文件

[a#1,b#2,c#3]
[a#4,b#5,c#6]
[a#7,b#8,c#9]

猪脚本

A = LOAD 'txt' AS (in: map[]);
B = FOREACH A GENERATE in#'a';
DUMP B;

我们知道我们可以获取键中的值。在上面的示例中,我使用了包含与键 "a" 相关的值的映射。 假设我不知道键,我想对关系中键的值进行分组并转储它。

(a,1,4,7)
(b,2,5,8)
(c,3,6,9)    

pig 是否允许此类操作或需要使用 UDF?请帮我解决这个问题。谢谢。

【问题讨论】:

【参考方案1】:

您可以创建一个自定义UDF,将地图转换为一个包(使用 Pig v0.10.0):

package com.example;

import java.io.IOException;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.pig.EvalFunc;
import org.apache.pig.data.BagFactory;
import org.apache.pig.data.DataBag;
import org.apache.pig.data.Tuple;
import org.apache.pig.data.TupleFactory;

public class MapToBag extends EvalFunc<DataBag> 

    private static final BagFactory bagFactory = BagFactory.getInstance();
    private static final TupleFactory tupleFactory = TupleFactory.getInstance();

    @Override
    public DataBag exec(Tuple input) throws IOException 
        try 
            @SuppressWarnings("unchecked")
            Map<String, Object> map = (Map<String, Object>) input.get(0);
            DataBag result = null;
            if (map != null) 
                result = bagFactory.newDefaultBag();
                for (Entry<String, Object> entry : map.entrySet()) 
                    Tuple tuple = tupleFactory.newTuple(2);
                    tuple.set(0, entry.getKey());
                    tuple.set(1, entry.getValue());
                    result.add(tuple);
                
            
            return result;

        
        catch (Exception e) 
            throw new RuntimeException("MapToBag error", e);
        
    

然后:

B = foreach A generate 
      flatten(com.example.MapToBag(in)) as (k:chararray, v:chararray);
describe B;
B: k: chararray,v: chararray

现在按键分组并使用嵌套的foreach:

C = foreach (group B by k) 
    value = foreach B generate v;
    generate group as key, value;
;
dump C;
(a,(1),(4),(7))
(b,(2),(5),(8))
(c,(3),(6),(9))

【讨论】:

我不认为最终嵌套的 foreach 会起作用......因为从 v0.9 开始,FOREACH 中不允许使用 FOREACH 此示例是在允许的 v0.10.0 中完成的。无论如何,我更新了我的答案以表明我使用的 Pig 版本。 我想我将不得不升级到 v0.10,因为我真的很想在嵌套的 foreach 中选择列。 :) @LorandBendig,我也是 PIG 的新手,也有同样的情况,我试过这个,但在执行时我得到 error 2015-01-03 11:21:24,655 [main] ERROR org.apache.pig.tools.grunt.Grunt - ERROR 1070: Could not resolve mupigudf.MyPigUDF using imports: [, java.lang., org.apache.pig.builtin., org.apache.pig.impl.builtin.] 你能告诉我什么是出错了,我也用谷歌搜索过,但不明白为什么会这样。 @MegaBytes 你不是忘记注册包含MyPigUDF的jar了吗?

以上是关于pig中map的分组键值的主要内容,如果未能解决你的问题,请参考以下文章

[677]. 键值映射

[java自学第九天]

java如何对一堆键值对数据分组

c++中map是有序的吗

使用 pig,如何解析和比较分组项目

Java之集合