Java Spark展平数据集映射列

Java Spark展平数据集映射列,java,apache-spark,rdd,Java,Apache Spark,Rdd,我有一个带有模式的RDD- Schema: { "type" : "struct", "fields" : [ { "name" : "cola", "type" : "string", "nullable" : true, "metadata" : { } }, { "name" : "mappedcol", "type" : { "type" : "map", "keyType" : "string",

我有一个带有模式的RDD-

Schema: {
  "type" : "struct",
  "fields" : [ 

 {
    "name" : "cola",
    "type" : "string",
    "nullable" : true,
    "metadata" : { }
  }, {
    "name" : "mappedcol",
    "type" : {
      "type" : "map",
      "keyType" : "string",
      "valueType" : "string",
      "valueContainsNull" : true
    },
    "nullable" : true,
    "metadata" : { }
  }, {
    "name" : "colc",
    "type" : "string",
    "nullable" : true,
    "metadata" : { }
  }]
  }
样本值:

{
cola : A1,
mappedcol : { mapped1: M1, mapped2: M2, mapped3: M3  }
colc : C1
}
我想把mappedcols的钥匙往上拉一层。基本上在一个级别上展平所有列

cola, mapped1, mapped2, mapped3, colc
A1, M1,M2,M3, C1

在Java中有一种优雅的方法吗?

可以使用点语法访问嵌套结构的单个元素,例如
select mappedcol。mapped1
将返回
M1
。其思想是使用以下点语法将模式转换为列名列表:

私有静态列表structToColNames(StructField[]字段,字符串前缀){
列表列=新的ArrayList();
for(结构字段:字段){
字符串fieldname=field.name();
if(field.dataType()instanceof StructType){
columns.addAll(
structToColNames(((StructType)field.dataType()).fields(),
前缀+字段名+“);
}
否则{
columns.add(前缀+字段名);
}
}
返回列;
}
该功能的结果可用于选择数据:

数据集df=spark.read().json(); StructField[]fields=df.schema().fields(); List colNames=structToColNames(字段“”); System.out.println(colNames); Column[]columns=colNames.stream().map(s->col(s)).toArray(Column[]::new); df.select(columns.show(); 印刷品

[cola,colc,mappedcol.mapped1,mappedcol.mapped2,mappedcol.mapped3]
+----+----+-------+-------+-------+
|可乐|可乐|地图1 |地图2 |地图3|
+----+----+-------+-------+-------+
|A1 | C1 | M1 | M2 | M3|
+----+----+-------+-------+-------+