Java Spark展平数据集映射列
我有一个带有模式的RDD-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",
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|
+----+----+-------+-------+-------+