gpt4 book ai didi

map - 将键值元组包转换为在 Apache Pig 中映射

转载 作者:行者123 更新时间:2023-12-04 06:20:13 25 4
gpt4 key购买 nike

我是 Pig 的新手,我想将一包元组转换为以每个元组中的特定值作为键的映射。基本上我想改变:
{(id1, value1),(id2, value2), ...}进入 [id1#value1, id2#value2]
我已经在网上找了一段时间,但似乎找不到解决方案。我试过了:

bigQMap = FOREACH bigQFields GENERATE TOMAP(queryId, queryStart);

但我最终得到了一袋 map (例如 {[id1#value1], [id2#value2], ...} ),这不是我想要的。如何从一袋键值元组中构建映射?

以下是我尝试运行的特定脚本,以防万一
rawlines = LOAD '...' USING PigStorage('`');
bigQFields = FOREACH bigQLogs GENERATE GFV(*,'queryId')
as queryId, GFV(*, 'queryStart')
as queryStart;
bigQMap = ?? how to make a map with queryId as key and queryStart as value ?? ;

最佳答案

TOMAP获取一系列对并将它们转换为 map ,因此它的使用方式如下:

-- Schema: A:{foo:chararray, bar:int, bing:chararray, bang:int}
-- Data: (John, 27, Joe, 30)
B = FOREACH A GENERATE TOMAP(foo, bar, bing, bang) AS m ;
-- Schema: B:{m: map[]}
-- Data: (John#27,Joe#30)

如您所见,语法不支持将包转换为 map 。据我所知,无法以纯 pig 映射的格式转换包。但是,您可以明确地写一个 java UDF去做这个。

注意:我对 java 不太有经验,所以这个 UDF 可以很容易地改进(添加异常处理,如果一个键添加两次会发生什么等)。但是,它确实完成了您需要的功能。
package myudfs;
import java.io.IOException;
import org.apache.pig.EvalFunc;

import java.util.Map;
import java.util.HashMap;
import java.util.Iterator;
import org.apache.pig.data.Tuple;
import org.apache.pig.data.DataBag;

public class ConvertToMap extends EvalFunc<Map>
{
public Map exec(Tuple input) throws IOException {
DataBag values = (DataBag)input.get(0);
Map<Object, Object> m = new HashMap<Object, Object>();
for (Iterator<Tuple> it = values.iterator(); it.hasNext();) {
Tuple t = it.next();
m.put(t.get(0), t.get(1));
}
return m;
}
}

将脚本编译成 jar 后,可以像这样使用它:
REGISTER myudfs.jar ;
-- A is loading some sample data I made
A = LOAD 'foo.in' AS (foo:{T:(id:chararray, value:chararray)}) ;
B = FOREACH A GENERATE myudfs.ConvertToMap(foo) AS bar;
foo.in的内容:
{(open,apache),(apache,hadoop)}
{(foo,bar),(bar,foo),(open,what)}

来自 B 的输出:
([open#apache,apache#hadoop])
([bar#foo,open#what,foo#bar])

另一种方法是使用 python to create the UDF :

myudfs.py
#!/usr/bin/python

@outputSchema("foo:map[]")
def BagtoMap(bag):
d = {}
for key, value in bag:
d[key] = value
return d

这是这样使用的:
Register 'myudfs.py' using jython as myfuncs;
-- A is still just loading some of my test data
A = LOAD 'foo.in' AS (foo:{T:(key:chararray, value:chararray)}) ;
B = FOREACH A GENERATE myfuncs.BagtoMap(foo) ;

并产生与 Java UDF 相同的输出。

奖金:
由于不太喜欢 map , here是一个链接,解释了如何仅使用键值对来复制 map 的功能。由于您的键值对在一个包中,您需要在嵌套的 FOREACH 中执行类似映射的操作。 :
-- A is a schema that contains kv_pairs, a bag in the form {(id, value)}
B = FOREACH A {
temp = FOREACH kv_pairs GENERATE (key=='foo'?value:NULL) ;
-- Output is like: ({(),(thevalue),(),()})

-- MAX will pull the maximum value from the filtered bag, which is
-- value (the chararray) if the key matched. Otherwise it will return NULL.
GENERATE MAX(temp) as kv_pairs_filtered ;
}

关于map - 将键值元组包转换为在 Apache Pig 中映射,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17847970/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com