【问题标题】:PigLatin map key valuePigLatin 映射键值
【发布时间】:2012-06-08 15:46:21
【问题描述】:

我第一次使用一些 PigLatin 代码,并希望能够通过首先将键值生成为 chararray,然后使用该键来访问映射中的值。例如,categoryIds 是我的地图,

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

这是我收到的错误: ERROR 1000:解析时出错。在第 28 行第 64 列遇到“”catId“”。 期待其中之一: “空值” ... ... ... “空” ...

我试图做的事情是不可能的吗?每次使用地图时是否需要明确说明键值(例如:categoryIds#'51')?

【问题讨论】:

    标签: map hadoop apache-pig


    【解决方案1】:

    据我所知,Pig 没有提供任何内置方法来从地图中获取密钥。对于 map 字段,只能使用 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();
    }
    

    【讨论】:

      【解决方案2】:

      在您的代码中,catIds 只有两个字段 - elementIdcatId,并且您尝试在第二行访问 categoryIds。所以它不会工作。请修复它。

      具体如何访问map值,需要将key用引号括起来,例如categoryIds#'catId'

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-07-23
        • 2017-08-08
        • 2013-07-31
        • 2013-03-12
        • 1970-01-01
        相关资源
        最近更新 更多