如何使用Pig脚本生成嵌套的Avro字段?

时间:2014-03-14 22:32:57

标签: hadoop apache-pig

我是Pig新手,我的输入数据格式为

Record1:
{
  label:int,
  id: long
},
Record 2:
{
 ...
}
...

我想要的输出是

Record 1:
{
  data:{
    label:int,
    id:long
  }
}, 
Record 2:
{
  ...
}
...

我试过了:

result = FOREACH input GENERATE (id, label) AS data;

但这导致嵌套的元组结构如下所示:

Record 1:
{
  data:{
   TUPLE_1:{
      label:int,
      id: long
   }
  }
}

我怎么能摆脱另一个包“TUPLE_1”,看起来我错过了一个微不足道的设置。

2 个答案:

答案 0 :(得分:0)

您可能需要在存储数据时指定架构。 如果使用org.apache.pig.piggybank.storage.avro.AvroStorage,则可以将模式定义作为参数。

result = FOREACH input GENERATE label:int, id:long;
STORE result INTO 'result.avro' USING org.apache.pig.piggybank.storage.avro.AvroStorage('schema', '{"type": "record","name": "data","fields": [{"name": "label","type": "int"},{"name": "id", "type": "long"}]}');

答案 1 :(得分:0)

我的最终解决方案是这样的:

首先要创建一个具有特定模式的avro文件,我确保为AvroStorage执行以下模式配置:

STORE sth INTO 'someplace' USING AvroStorage('schema','
  {
    ### AN AVRO SCHEMA JSON STRING ###
  }
');

我发现使用这种缩进确实有助于使架构定义更清晰。而且我还需要确保我逃避所有特殊字符,尤其是引号(它们可能存在于“doc”中,这很棘手)。

然后为了使sth具有正确的存储结构,我需要正确构建整个数据结构。如果已经存在一些目标数据文件的示例,则可以使用DESCRIBE。在我之前的问题中,代码应如下所示:

in = LOAD '$INPUT_PATHS' USING AvroStorage();
in = FOREACH in GENERATE foo.label AS label, bar.id AS id;
out = FOREACH in GENERATE TOMAP('id', (long)id, 'label', (chararray)label) AS data;
RMF $OUTPUT_PATH;
STORE out INTO '$OUTPUT_PATH USING AvroStorage('schema',
  {
    "type": "records",
    "name": "XXItem",
    "namespace": "com.xxx.xxx",
    "fields": [
      {
       "name": "data",
       "type":  {"type": "map", "values" : ["string", "long", "int"]}
      }
    ]
  }
');