如何在Spark SQL中推断序列化JSON列的模式?

5

我有一个表格,其中有1列是序列化的JSON。我想对这个JSON列应用模式推断。但我不知道要传递什么模式作为JSON提取的输入(例如:使用from_json函数)。

我可以在Scala中这样做:

val contextSchema = spark.read.json(data.select("context").as[String]).schema
val updatedData = data.withColumn("context", from_json(col("context"), contextSchema))

我如何将此解决方案转换为纯Spark-SQL?
4个回答

2

对于 spark-sql,使用 toDDL 生成模式,然后在 from_json 中使用该模式。

例如:

df.show(10,false)
//+---+-------------------+
//|seq|json               |
//+---+-------------------+
//|1  |{"id":1,"name":"a"}|
//+---+-------------------+

val sch=spark.read.json(df.select("json").as[String]).schema.toDDL
//sch: String = `id` BIGINT,`name` STRING

df.createOrReplaceTempView("tmp")

spark.sql(s"""select seq,jsn.* from (select *,from_json(json,"$sch") as jsn  from tmp)""").
show(10,false)
//+---+---+----+
//|seq|id |name|
//+---+---+----+
//|1  |1  |a   |
//+---+---+----+

我正在寻找纯Spark-SQL解决方案。我想要应用这个解决方案的环境只支持Spark-SQL语句。 - Harshit

1
您可以使用schema_of_json()函数来推断JSON模式。
select from_json(<column_name>, schema_of_json(<sample_JSON>)) from <table> 

我没有样本JSON。希望能够在表格中获取它。 - Harshit
JSON的结构/模式是固定的吗?如果是这样,您可以形成模式并将其传递给from_json函数。 - Mohana B C
不,JSON 结构/模式会随输入而改变。 - Harshit

0
我找到了一个解决方法:
  1. 将其转换为RDD,并使用Spark DataFrame进行读取
spark
  .read
  .option("inferSchema", True)
  .json(
      df.rdd.map(
          lambda rec: rec.context
      )
  )

如果事先知道字段/路径,我们可以使用。
df.select(json_tuple(col("context"),"<json path or attribute>").alias("field_name")).show()

0
你可以试试这个:
from pyspark.sql import SparkSession

spark = SparkSession.builder.appName("JsonInferSchema").getOrCreate()

data = spark.createDataFrame([
    (1, '{"name":"John", "age":30}'),
    (2, '{"name":"Doe", "age":25}')
], ["id", "context"])

data.createOrReplaceTempView("tempTable")

query = """
SELECT 
    id, 
    context,
    get_json_object(context, '$.name') as name,
    get_json_object(context, '$.age') as age
FROM tempTable
"""

updatedData = spark.sql(query)

updatedData.show()

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接