无法从数据框中提取数组/列表,AnalysisException:需要struct类型但得到二进制文件

时间:2017-08-15 00:11:51

标签: java apache-spark dataframe apache-spark-sql spark-structured-streaming

我有一个带字符串[]的数据集,我正在努力从中提取列。这是代码

import static org.apache.spark.sql.functions.col;

//Read parquet data
Dataset<Row> readerDF = spark.readStream().format("parquet").

List<String> columns = Arrays.asList("city","country");
//Interested in only field in data for now 'fieldMap' which is Map<String,String>

Dataset<String[]> stringArrDF = readerDF.map((MapFunction<Row, String[]>) row -> {                
    Map<String,String> fields = row.getJavaMap(row.fieldIndex("fieldMap"));
    List<String> columnList = new ArrayList<>();                
    columns.forEach(columnName ->
    {
        columnList.add(fields.getOrDefault(columnName, ""));
    });
    return columnList.toArray(new String[columns.size]);
}, Encoders.kryo(String[].class));

//I was expecting to extract city here:
Dataset ds = stringArrDF.select(col("value").getItem(1).as("city"));

但是它失败了以下例外。

  

线程“main”中的异常org.apache.spark.sql.AnalysisException:   无法从值#22中提取价值;

如何从数据集中访问String []或List字段?

1 个答案:

答案 0 :(得分:1)

您收到以下错误。

  

线程中的异常&#34; main&#34; org.apache.spark.sql.AnalysisException:   无法从值#22中提取值:需要结构类型但是得到了二进制文件;

您正在使用Encoders.kryo(String[].class)来创建stringArrDF。如果您查看Encoders.kryo的文档,则说明

  

创建一个使用Kryo序列化T类型对象的编码器。这个   编码器将T映射到单字节数组(二进制)字段。

使用spark.implicits().newStringArrayEncoder()对String []进行编码。