将 Spark DF 转换为具有不同字段名称的 DS

Convert Spark DF to a DS with different fields names

我想将 Spark 数据帧转换为具有不同字段名称的 POJO 数据集。我有一个字段的数据框:namedate_of_birth,它们的类型是 StringTypeDateType

还有一个 POJO:

public class Person implements Serializable {
    private String name;
    private Date dateOfBirth;
}

使用以下代码成功将其转换为数据集:

Encoder<Person> personEncoder =  Encoders.bean(Person.class); 
Dataset<Person> personDS = result.as(personEncoder);
List<Person> personList = personDS.collectAsList();

仅当我在此之前将数据框的列名更改为 Person POJO 的列名时。有什么方法可以让 Spark 从 POJO 端在字段之间进行映射吗?

我考虑过Gson的@SerializedName(“date_of_birth”)但是没有影响。

如果您有名称映射,比如在地图中,您可以在将数据框转换为数据集之前使用它来重命名列。

可以这样写:

// I create the map, but it could be read from a config file for instance
Map<String, String> nameMapping = new java.util.HashMap<>();
nameMapping.put("id", "name");
nameMapping.put("date", "dateOfBirth");

Column[] renamedColumns = nameMapping
                .entrySet()
                .stream()
                .map(x -> col(x.getKey()).alias(x.getValue()))
                .collect(Collectors.toList())
                .toArray(new Column[0]);

result.select(renamedColumns).as(personEncoder)

我不知道具体的注释。但是,这是我的解决方法。

我会创建一个具有我想要的形状的特定数据框,然后将其导出。

看起来像:

Dataset<Row> exportDf = df
    .withColumn("dateOfBirth",
        col("date_of_birth").cast(DataTypes.StringType))
    .drop("date_of_birth");

我写的完整示例可以在这里找到:https://github.com/jgperrin/net.jgp.labs.spark/tree/master/src/main/java/net/jgp/labs/spark/l999_scrapbook/l002

备注:

  • 我假设您代码中的 resultDataset<Row>
  • 我使用字符串作为您的日期,因为 Spark 对于将日期转换为 POJO 中的字符串有点敏感。如果您需要专门针对此问题的帮助,请创建另一个 SO 问题,我会很乐意查看。