处理Spark数据帧列中的json字符串

时间:2017-05-25 20:16:14

标签: apache-spark

当我寻找在数据帧的字符串列中解析json的方法时,我会继续运行更简单地读取json文件源的结果。我的源实际上是一个hive ORC表,其中一个列中的一些字符串是json格式。我真的很想把它转换为像地图一样解析的东西。

我无法找到办法执行此操作:

import java.util.Date
import org.apache.spark.sql.Row
import scala.util.parsing.json.JSON

val items = sql("select * from db.items limit 10")
//items.printSchema
val internal = items.map {
  case Row(externalid: Long, itemid: Long, locale: String,
           internalitem: String, version: Long,
           createdat: Date, modifiedat: Date)
       => JSON.parseFull(internalitem)
}

我认为这应该有用,但也许有更强烈的 Spark 方式,因为我收到以下错误:

java.lang.ClassNotFoundException: scala.Any
 at scala.reflect.internal.util.AbstractFileClassLoader.findClass(AbstractFileClassLoader.scala:62)

具体来说,我的输入数据看起来大致如下:

externalid, itemid, locale, internalitem, version, createdat, modifiedat
       123,    321, "en_us", "{'name':'thing','attr':{
                               21:{'attrname':'size','attrval':'big'},
                               42:{'attrname':'color','attrval':'red'}
                              }}",              1, 2017-05-05…, 2017-05-06…

是的,它不是RFC 7158。

attr个键可以是任何80,000个值中的5到30个,所以我希望得到类似的东西:

externalid, itemid, locale, internalitem, version, createdat, modifiedat
       123,    321, "en_us", "{"name':"thing","attr":[
                               {"id":21,"attrname':"size","attrval":"big"},
                               {"id":42,"attrname":"color","attrval":"red"}
                              ]}",              1, 2017-05-05…, 2017-05-06…

然后将internalitem展平为字段并展开attr数组:

externalid, itemid, locale, name, attrid, attrname attrval, version, createdat, modifiedat
       123,    321, "en_us", "thing", 21,   "size",  "big",       1, 2017-05-05…, 2017-05-06…
       123,    321, "en_us", "thing", 21,  "color",  "red",       1, 2017-05-05…, 2017-05-06…

1 个答案:

答案 0 :(得分:2)

我从来没有使用过这样的计算,但我有一个建议:

在对您自己的列执行任何操作之前,只需检查包含一大堆有用函数的sql.functions包,以处理日期提取和格式化,字符串连接和拆分等列, ...它还提供了一些函数来处理json对象,例如:from_jsonjson_tuple

要使用这些方法,您只需要导入它们并在这样的select方法中调用它们:

import spark.implicits._
import org.apache.spark.sql.functions._
val transofrmedDf = df.select($"externalid", $"itemid", … from_json($"internalitem", schema), $"version" …)

首先,您必须为json列创建架构并将其放入schema变量

希望它有所帮助。