【发布时间】:2017-05-25 20:16:14
【问题描述】:
当我寻找在数据框的字符串列中解析 json 的方法时,我不断遇到更简单地读取 json 文件源的结果。我的源实际上是一个配置单元 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…
【问题讨论】:
-
此代码通过解析源数据帧中的数据字段来创建一个新数据帧。
spark.sqlContext.read.json(df.select("col1").rdd.map(_.getAs[String](0))) -
@rogue-one 是的,所以当你这样做时,你不能在解析 json 之后再引用其他列,对吧?例如,如果我将 json 中的内容展平并想要输出所有列以及新列,那将如何完成?
-
你看过这个吗:stackoverflow.com/questions/35068792/…——我认为explode方法应该可以帮助你做到这一点。当然 - 当你来自兽人时,它可能不起作用。这可以帮助您提取 JSON stackoverflow.com/questions/34069282/…
标签: apache-spark