1
votes

I'm attempting to write a Spark Scala DataFrame Column as an array of bytes. I have a DataFrame that consists of two columns. The first column is a string and the second is a Map from Strings to Longs.

For example,

user_id | map
"ac2"   | Map("c2" -> 1, "b3" -> 5)

I want to write the map column as an array of bytes. So far I've attempted to use Jackson with the following UDF:

val writeJackson = udf { x: Map[String, Long] =>
    jacksonWriter.writeValueAsBytes(x)
}

val df2 = df.withColumn("jacksonMap", writeJackson($"map"))

but this fails because of

java.io.NotSerializableException: com.fasterxml.jackson.module.paranamer.shaded.CachingParanamer

Is there a way to get this to work with Jackson, and if not is there a different library that will let me write this Spark column as a byte array?

1

1 Answers

0
votes

I am able to convert to ByteArray and get the output with the following code. Using spark 1.6.2.

object DF {

  def main(args: Array[String]): Unit = {

    val mapper: ObjectMapper = new ObjectMapper
    mapper.registerModule(DefaultScalaModule)

    val df = Seq(
      ("ac2", Map("c2" -> 1, "b3" -> 5))
    ).toDF("id", "map")

    df.show(false)
    //output
    // +---+---------------------+
    // |id |map                  |
    // +---+---------------------+
    // |ac2|Map(c2 -> 1, b3 -> 5)|
    // +---+---------------------+
    val getByteArray = udf((map: Map[String, Int]) => mapper.writeValueAsBytes(map))

    df.withColumn("bytearray", getByteArray($"map")).show(false)

    //output
    // +---+---------------------+----------------------------------------------+
    // |id |map                  |bytearray                                     |
    // +---+---------------------+----------------------------------------------+
    // |ac2|Map(c2 -> 1, b3 -> 5)|[7B 22 63 32 22 3A 31 2C 22 62 33 22 3A 35 7D]|
    // +---+---------------------+----------------------------------------------+
  }
}