【发布时间】:2019-08-31 15:41:25
【问题描述】:
我想对多个“行”json 字符串进行一些查询。我所说的多个 json 字符串是指这样组织的 json 字符串:
[{
"id" : 5,
"name" : "Jemmy overy",
"data" : {...},
"link" : "http:...",
},
{
"id" : 6,
"name" : "John Smith",
"data" : {...},
"link" : "http:...",
}]
这是我尝试做的:
首先,我有 多个 json 文件,我从 HDFS 获得:
val df = spark
.read
.format(com.databricks.spark.avro)
.load(namenodeURI)
此时我的 json 文件的架构分为两个字段:
- 标题
- 身体
我要处理的列是 body,所以我使用 spark-sql 只选择了 JSON 格式的数据列。
df.createOrReplaceTempView("Rawdata")
import spark.implicits._
val strBody = spark
.sql("SELECT body from Rawdata")
.as[String]
.collect
.mkString
记住我有多个 json 文件,所以我有多个主体。我真的不知道如何从查询中获取结果,我试图将其作为字符串获取。
我的目标是对 strBody 字符串进行一些查询。我首先使用编码器将其转换为数据集:
val ds = spark.createDataset(strBody :: Nil)
val schema = Encoders.product[Root].schema
val ds2 =
spark
.read
.schema(schema)
.json(ds).as[Root]
Root是一个case类,对应body中的Json schema。
当我想打印我的正文的特定字段的每个内容时,它只打印从我的 sql 查询返回的第一个正文的字段的内容:
ds2.map(x => x.someField.someAnotherNestedField).foreach(println(_))
// print only one element, the first element from the strBody variable
当我从查询中获取字符串以匹配多行json字符串的语法时,我尝试添加前缀后缀和分隔符:
val strBody = spark
.sql("SELECT body from Rawdata")
.as[String]
.collect
.mkString("[",",\n","]")
由于我使用插入“\n”字符,所以在最后读取数据集时指定了多行选项:
val ds = spark.createDataset(strBody :: Nil)
val schema = Encoders.product[Root].schema
val ds2 =
spark
.read
.option("multiline","true")
.schema(schema)
.json(ds).as[Root]
然后我得到一个 NullPointerException。实际上 ds2 不包含任何值。
有人知道如何解决这个问题吗?
【问题讨论】:
-
您能否在数据帧上发布与您的代码示例匹配的示例以及
printSchema。还有火花版本。
标签: json scala apache-spark apache-spark-sql