Java ApacheSpark——需要基于结果元数据映射动态实现withColumn

Java ApacheSpark——需要基于结果元数据映射动态实现withColumn,java,apache-spark,apache-spark-sql,apache-spark-dataset,Java,Apache Spark,Apache Spark Sql,Apache Spark Dataset,我有一个用例,需要对已经加载的数据进行一些数据更正。假设元数据在hbase中,一个colfamily下有逻辑主键,另一个ColumnUpdate下有ColumnUpdate。假设我有一个经过过滤的数据帧,其中有一条记录,我需要对其进行更新(使用spark sql进行过滤)。ColName和Colvalues位于java映射中。我知道我们可以使用ColUnmm来更新或向现有DF添加新的col,但在这种情况下,我需要根据元数据多次应用withColumn,即需要更正数据的列数。我不能通过迭代映射在f

我有一个用例,需要对已经加载的数据进行一些数据更正。假设元数据在hbase中,一个colfamily下有逻辑主键,另一个ColumnUpdate下有ColumnUpdate。假设我有一个经过过滤的数据帧,其中有一条记录,我需要对其进行更新(使用spark sql进行过滤)。ColName和Colvalues位于java映射中。我知道我们可以使用ColUnmm来更新或向现有DF添加新的col,但在这种情况下,我需要根据元数据多次应用withColumn,即需要更正数据的列数。我不能通过迭代映射在for循环中进行此操作,因为数据帧是不可变的,也不鼓励使用switch case。还有一个不应使用scala API的限制

Dataset<Row> existingdata = sparksession.read
      .format(com.databricks.spark.avro)
      .load(myhdfslocation);

Map<byte[],byte[]> colUpdates = result.getFamily("TK")//result of hbase get
Set<byte[]> colUpdateKeys = colUpdates.keySet();
for(byte[] eachkey : colUpdateKeys ){
    Dataset<Row> updatedDF =  
             existingdata.withColumn(
                existingdata.col(Bytes.toString(eachkey)),
                "value from themetadatamap"
             );
}
Dataset existingdata=sparksession.read
.format(com.databricks.spark.avro)
.荷载(myhdfslocation);
Map colUpdates=result.getFamily(“TK”)//hbase get的结果
设置colUpdateKeys=colUpdates.keySet();
for(字节[]eachkey:colupdatekey){
Dataset updatedDF=
现有Data.withColumn(
existingdata.col(Bytes.toString(eachkey)),
“MetadataMap中的值”
);
}
到目前为止,我有两种方法,一种是使用切换案例(这不是最佳的,因为它不是保持这么多切换案例的好方法),另一种是将hbase元数据作为spark数据帧读取,然后应用spark连接来获得结果数据集。
如果有人能建议实现此用例的最佳方法,这将非常有帮助。:)

尽管您不能改变数据帧,但您可以更新引用它的变量:-)


这将使用沿袭中最新数据帧的值覆盖
existingdata
变量,这样在循环之后,
existingdata
具有所有列。

“MetadataMap中的值”
来自相同的
existingdata
数据帧?不。它是colupdates映射中的值。此映射具有要更新为键的列名,该值是列值。existingdata=existingdata。withColumn(…)此行将抛出重新初始化错误,因为数据帧是不可变的,如果一个数据帧一旦初始化就不能为新值更改。数据帧是不可变的,这意味着您不能更改数据帧对象。这并不意味着不能用其他对象替换数据帧变量的对象值
existingdata=existingdata.withColumn()
将在旧数据框的基础上创建一个新的数据框,然后覆盖变量的值。即使我以类似的方式思考并保留类似类型的代码,但在运行时它会引发重新初始化错误。。您可以通过执行类似的代码来尝试spark shell。它甚至不允许更改引用变量。无论如何,我将再次运行,并会让您知道。
for(byte[] eachkey : colUpdateKeys ){
    existingdata =  
             existingdata.withColumn(
                existingdata.col(Bytes.toString(eachkey)),
                "value from themetadatamap"
             );
}