2012-06-08 4 views
1

Я работаю с кодом PigLatin в первый раз и хочу иметь возможность получать доступ к значениям на карте, сначала генерируя значение ключа как chararray, а затем используя этот ключ. Например, с categoryIds быть мою карту,Значение ключа карты PigLatin

catIds = foreach filteredContexts generate elementId,SUBSTRING(categoryAndConfidence,0,2) as catId; 
categoryNames = foreach catIds generate elementId, categoryIds#catId as catName; 

Это ошибка я получаю: ОШИБКА 1000: Ошибка при разборе. Обнаружен "«CatID "" в строке 28, столбец 64. Ожидал один из: "нулевой" ... ... ... "нуль" ...

Это то, что я пытаясь сделать невозможным? Нужно ли явно указывать значение ключа (например: categoryIds # '51 ') каждый раз, когда я использую карту?

ответ

0

В коде catIds имеет только два поля - elementId и catId, и вы пытаетесь получить доступ к categoryIds во второй строке. Так что это не сработает. Пожалуйста, исправьте это.

В частности о том, как получить доступ к значениям карты, вам необходимо заключать ключ в кавычки, например categoryIds#'catId'

2

Насколько я знаю, Свинья не предусматривает каких-либо встроенных в пути, чтобы получить ключ от карты. С полем карты вы можете получить свой размер только с помощью функции SIZE, проверить, не пусто ли она с помощью функции IsEmpty или использовать map_field # 'key' для поиска значения данного ключа.

Я сам написал несколько UDF, чтобы помочь мне лучше работать над типом данных карты. Одна из моих функций может оказаться полезной для вас - MapToBag - которая может конвертировать карту :map[value_type] в сумку :bag{:tuple(key:chararray, value:value_type)}. С сумкой вы можете либо получить ключ, либо применить операцию FLATTEN.

package com.XXX.YYY.ZZZ; 

import org.apache.pig.EvalFunc; 
import org.apache.pig.FuncSpec; 
import org.apache.pig.data.*; 
import org.apache.pig.impl.logicalLayer.FrontendException; 
import org.apache.pig.impl.logicalLayer.schema.Schema; 

import java.io.IOException; 
import java.util.ArrayList; 
import java.util.List; 
import java.util.Map; 

public class MapToBag extends EvalFunc<DataBag> { 

    @Override 
    public DataBag exec(Tuple input) throws IOException { 
     if (input == null || input.size() == 0) { 
      return null; 
     } 

     @SuppressWarnings("unchecked") 
     Map<String, Object> map = (Map<String, Object>) input.get(0); 
     if (map == null || map.isEmpty()) { 
      return null; 
     } 

     DataBag bag = bagFactory.newDefaultBag(); 
     for (String key : map.keySet()) { 
      Object value = map.get(key); 
      Tuple oneKeyTuple = tupleFactory.newTuple(2); 
      oneKeyTuple.set(0, key); 
      oneKeyTuple.set(1, value); 
      bag.add(oneKeyTuple); 
     } 

     return (bag.size() == 0) ? null : bag; 
    } 

    @Override 
    public Schema outputSchema(Schema input) { 
     try { 
      Schema innerSchema = new Schema(); 
      innerSchema.add(new Schema.FieldSchema("key", DataType.CHARARRAY)); 
      innerSchema.add(getMapValueSchema(input)); 
      Schema tupleSchema = new Schema(new Schema.FieldSchema(null, innerSchema, DataType.TUPLE)); 
      return new Schema(new Schema.FieldSchema(null, tupleSchema, DataType.BAG)); 
     } catch (FrontendException e) { 
      return new Schema(new Schema.FieldSchema(null, DataType.BAG)); 
     } 
    } 

    protected Schema.FieldSchema getMapValueSchema(Schema input) throws FrontendException { 
     if (input == null || input.size() == 0) { 
      return null; 
     } 
     Schema.FieldSchema mapField = input.getField(0); 
     if (mapField.type != DataType.MAP) { 
      return null; 
     } 

     Schema valueSchema = mapField.schema; 
     if (valueSchema == null || valueSchema.size() == 0) { 
      return null; 
     } 
     Schema.FieldSchema valueField = valueSchema.getField(0); 
     valueField.alias = "value"; 
     return valueField; 
    } 

    @Override 
    public List<FuncSpec> getArgToFuncMapping() throws FrontendException { 
     List<FuncSpec> funcList = new ArrayList<FuncSpec>(); 
     funcList.add(new FuncSpec(this.getClass().getName(), new Schema(new Schema.FieldSchema(null, DataType.MAP)))); 
     return funcList; 
    } 

    private static TupleFactory tupleFactory = TupleFactory.getInstance(); 
    private static BagFactory bagFactory = BagFactory.getInstance(); 
} 
Смежные вопросы