Я пытаюсь преобразовать DataSet в объект Java.
Схема похожа на
root
|-- deptId: long (nullable = true)
|-- depNameName: string (nullable = true)
|-- employee: array (nullable = true)
| |-- element: struct (containsNull = true)
| | |-- firstName: string (nullable = true)
| | |-- lastName: string (nullable = true)
| | |-- phno: Long (nullable = true)
| | | |-- element: integer (containsNull = true)
Я создал классы pojo Like.
class Department {
private Long deptId;
private String depName;
private List<Employee> employess;
//with getter setters and no argument constructor
}
class Employee {
private String firstName;
private String lastName;
private List<Long> phno;
//With getter setter and no argument constructor
}
Теперь вот код, который я пытаюсь преобразовать.
Dataset<Row> ds = this.spark.read().parquet(Parquet file path);
Dataset<Department> departmentDataset =
ds.as(Encoders.bean(Department.class));
JavaRDD<String> rdd =
departmentDataset.toJavaRDD().map((Function<Department, String>) v -> {
StringBuilder sb = new StringBuilder();
sb.append("deptId").append(v.getDeptID());
if(!CollectionUtil.isListNullOrEmpty(v.employee))
sb.append("FirstName").append(v.getEmployee().get(0).getName);
if(!CollectionUtil.isListNullOrEmpty(v.getEmployee().getPhno()))
sb.append("Ph
number").append(v.getEmployee().getPhno().get(0));
return sb.toString();
});
Но этот код не работает. Не удалось с org.apache.hadoop.yarn.server.nodemanager.containermanager.runtime.ContainerExecutionException
. Но я могу преобразовать это используя конструктор на основе строк, где мне нужно жестко закодировать имя столбца.
Как
public Department(Row row)
{
this.employees = new ArrayList<Employee>
this.deptaID = (Long)row.getAs("deptId");
List rowList = (List)row.getList(row.fieldIndex("employee"));
if (rowList!=null) {
for (Row r : rowList) {
Employee obj = new Employee(r);
employees.add(obj);
}
}
public Employee(Row row)
{
this.phno = new ArrayList<Long>
this.firstName = (Long)row.getAs("firstName");
List rowList = (List)row.getList(row.fieldIndex("phno"));
if (rowList!=null) {
for (Row r : rowList) {
phno.add(r);
}
}
JavaRDD<Department> rdd = ds.toJavaRDD().map(Department::new);
JavaRDD<String> rdd = rdd.map((Function<Department, String>) v -> {
StringBuilder sb = new StringBuilder();
sb.append("deptId").append(v.getDeptID());
if(!CollectionUtil.isListNullOrEmpty(v.employee))
sb.append("FirstName").append(v.getEmployee().get(0).getName);
if(!CollectionUtil.isListNullOrEmpty(v.getEmployee().getPhno()))
sb.append("Ph
number").append(v.getEmployee().getPhno().get(0));
return sb.toString();
});
При таком подходе я получаю успех. Но он включает в себя много жесткого кодирования имени схемы и все. Так что ищем более элегантное решение.
Пожалуйста, предложите лучшее решение для этой проблемы.