如何在scala中获取JSON的结构
我有很多没有结构化的JSON文件,我想得到一个更深层次的元素和所有元素 例如:如何在scala中获取JSON的结构,json,scala,apache-spark,Json,Scala,Apache Spark,我有很多没有结构化的JSON文件,我想得到一个更深层次的元素和所有元素 例如: { "menu": { "id": "file", "popup": { "menuitem": { "module"{ "-vdsr": "New", "-sdst": "Open", "-mpoi": "Close"
{
"menu": {
"id": "file",
"popup": {
"menuitem": {
"module"{
"-vdsr": "New",
"-sdst": "Open",
"-mpoi": "Close" }
...
}
}
在这种情况下,结果将是:
menu.popup.menuitem.module.-vdsr
menu.popup.menuitem.module.-sdst
menu.popup.menuitem.module.-mpoi
我尝试了Jackson
和Json4s
,它们可以有效地执行最后一个值,但我不知道如何获得整个结构
我想让它在非常大的JSON文件上运行ApacheSpark作业,每个文件的结构都非常复杂。我也尝试过sparkSQL,但如果我不知道整个结构,我就无法得到它。您要求做的基本上是一个对象的定义,其中JSON对象被认为是具有命名分支的节点,其他JSON类型被认为是叶子。有很多方法可以做到这一点。您可以考虑创建一个递归函数来探索整个树。下面是一个在
PlayJson
中工作的示例,但在其他库中应该没有什么不同:
import play.api.libs.json._
def unfold(json: JsValue): Seq[String] = json match {
case JsObject(kvps) => kvps.flatMap {
case (key, value) => unfold(value).map(path => s"$key.$path")
}
case _ => Seq("")
}
新方法的优点在于,当您加载数据时,它会自动推断模式。它通过对整个数据集进行一次性传递来实现 我建议您加载json,然后进行转换,看看能得到什么。您可以删除或选择列的子集、筛选行、聚合、映射到列上,等等 例如:
// you can use globing to load multiple files
val jsonTbl = sqlContext.load("path to json file", "json")
// print the inferred schema
jsonTbl.printSchema
// now you can use the DataFrame API to transform the data set, e.g.
val outputTbl = jsonTbl
.filter("menu.popup.menuitem.module.-vdsr = 'Some value'")
.groupBy("menu.popup.menuitem.module.-vdsr").count
.select("menu.popup.menuitem.module.-sdst", "other fields/columns")
outputTbl.show