当我寻找在数据帧的字符串列中解析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…
答案 0 :(得分:2)
我从来没有使用过这样的计算,但我有一个建议:
在对您自己的列执行任何操作之前,只需检查包含一大堆有用函数的sql.functions包,以处理日期提取和格式化,字符串连接和拆分等列, ...它还提供了一些函数来处理json对象,例如:from_json
和json_tuple
。
要使用这些方法,您只需要导入它们并在这样的select方法中调用它们:
import spark.implicits._
import org.apache.spark.sql.functions._
val transofrmedDf = df.select($"externalid", $"itemid", … from_json($"internalitem", schema), $"version" …)
首先,您必须为json列创建架构并将其放入schema
变量
希望它有所帮助。