如何将一列与avro文件中的其他列映射?

时间:2017-07-05 10:28:20

标签: scala apache-spark spark-avro

我正在使用Spark 2.1.1和Scala 2.11.8

这个问题是我早期问题的延伸:

How to identify null fields in a csv file?

更改是,我现在正在从avro文件中读取数据,而不是从CSV文件中读取数据。这是我正在读取数据的avro文件的格式:

var ttime: Long = 0;
var eTime: Long = 0;
var tids: String = "";
var tlevel: Integer = 0;
var tboot: Long = 0;
var rNo: Integer = 0;
var varType: String = "";
var uids: List[TRUEntry] = Nil;

我正在单独的类中解析avro文件。

我必须以与上面发布的链接的接受答案中提到的相同的方式将tids列映射到每个uid,除非这次是从avro文件而不是格式良好的csv文件。我怎样才能做到这一点?

这是我尝试使用的代码:

val avroRow = spark.read.avro(inputString).rdd
  val avroParsed = avroRow
    .map(x => new TRParser(x))
    .map((obj: TRParser) => ((obj.tids, obj.uId ),1))
    .reduceByKey(_+_)
    .saveAsTextFile(outputString)

在obj.tids之后,必须单独映射所有uid列,以提供与上述链接的接受答案中提到的相同的最终输出。

这就是我解析avro文件解析类中所有uid的方法:

this.uids = Nil
    row.getAs[Seq[Row]]("uids")
    .foreach((objRow: Row) => 
      this.uids ::= (new TRUEntry(objRow))
    )

this.uids    
.foreach((obj:TRUEntry) => {
  uInfo += obj.uId + " , " + obj.initM.toString() + " , "
})   
P:如果这个问题看起来很愚蠢,我很抱歉,但这是我第一次遇到avro文件

1 个答案:

答案 0 :(得分:0)

可以通过传递相同的循环处理来完成

this.uids 

在主代码中:

 val avroParsed = avroRow
    .map(x => new TRParser(x))
    .map((obj: TRParser) => {
      val tId = obj.source.trim
      var retVal: String = ""
      obj.uids
        .foreach((obj: TRUEntry) => {
          retVal += tId + "," + obj.uId.trim + ":"
        })
        retVal.dropRight(1)
    })

 val flattened = avroParsed
 .flatMap(x => x.split(":"))
 .map(y => ((y),1))