基于现有数据集<row>和添加的HashMap

时间:2018-04-22 18:16:39

标签: java apache-spark dataset

我有一个基于JSON数据的Dataset<Row>。现在我想基于初始数据集BUT创建一个新的Dataset<Row>,其中添加了一个基于Java HashMap<String, String>数据类型的列,如

Dataset<Row> dataset2 = dataset1.withColumn("newColumn", *some way to specify HashMap<String, String> as the added column's datatype*);

使用这个新数据集,我可以创建一个行编码器,如

ExpressionEncoder<Row> dataset2Encoder = RowEncoder.apply(dataset2.schema());

然后应用地图功能,例如

dataset2 = dataset2.map(new XyzFunction(), dataset2Encoder)

澄清 我的初始数据集基于JSON格式的数据。我想要完成的是基于这个初始数据集BUT创建一个新数据集,并在MapFunction中添加一个新列。在创建初始数据集时添加列(withColumn)的想法将确保对于我希望在MapFunction中更新的列存在模式定义。但是,我似乎无法找到一种方法来修改传递给MapFunction类的调用(Row arg)函数的Row对象,或者在调用函数中使用RowFactory.create(...)创建一个新实例。我希望能够基于传递的Row对象的所有现有值和要添加到新行的新Map在MapFunction中创建Row实例。然后,编码器将从生成的模式中了解该新的/生成的列。我希望这能澄清我想要完成的事情......

1 个答案:

答案 0 :(得分:0)

你可以

import static org.apache.spark.sql.functions.*;
import org.apache.spark.sql.types.DataTypes;

df.withColumn("newColumn", lit(null).cast("map<string, string>"));

df.withColumn(
  "newColumn", 
  lit(null).cast(
    DataTypes.createMapType(DataTypes.StringType, DataTypes.StringType)
  )
);

但是为什么会这么间接?

Encoder<Row> enc = RowEncoder.apply(df.schema().add(
  "newColumn",
  DataTypes.createMapType(DataTypes.StringType, DataTypes.StringType)
));

根据您的具体操作,使用UserDefinedFunction可能会更加简单,并允许您完全跳过Encoders