#java #apache-spark #apache-spark-sql #pojo #apache-spark-dataset
Вопрос:
Я хочу преобразовать фрейм данных Spark в набор данных POJO с разными именами полей. У меня есть фрейм данных полей: name
, date_of_birth
, где их типы StringType
, DateType
.
И POJO из:
public class Person implements Serializable {
private String name;
private Date dateOfBirth;
}
Я успешно конвертирую его в dataset с помощью следующего кода:
Encoder<Person> personEncoder = Encoders.bean(Person.class);
Dataset<Person> personDS = result.as(personEncoder);
List<Person> personList = personDS.collectAsList();
Только если я перед этим изменю имена столбцов фрейма данных на имена пользователя POJO. Есть ли какой-либо способ указать Spark для сопоставления между полями со стороны POJO?
Я думал о Gson @SerializedName(“date_of_birth”)
, но это ни на что не повлияло.
Ответ №1:
Если у вас есть сопоставление имен, скажем, на карте, вы можете использовать его для переименования столбцов перед преобразованием фрейма данных в набор данных.
Это может быть написано так:
// 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)
Ответ №2:
Я не знаю конкретных аннотаций. Однако вот как я бы это решил.
Я бы создал определенный фрейм данных с нужной мне формой, а затем экспортировал его.
Это будет выглядеть так:
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.
Примечания:
- Я предполагаю, что
result
в вашем коде естьDataset<Row>
. - Я использовал строку для вашей даты, так как Spark немного беспокоился о преобразовании даты в строку в POJO. Если вам нужна помощь конкретно по этому вопросу, создайте еще один вопрос SO, я с радостью рассмотрю его.
Комментарии:
1. Спасибо за усилия! Это решение не совсем подходит, потому что я хочу, чтобы преобразование было динамическим, чтобы я мог добавить столбец и поле для DF и POJO, и это будет работать, не касаясь кода преобразования.
2. Я понимаю … будьте осторожны с типами данных, они могут обмануть вас при преобразовании … особенно даты!