如何从json字符串中提取值?

Posted

技术标签:

【中文标题】如何从json字符串中提取值?【英文标题】:How to extract values from json string? 【发布时间】:2016-08-30 23:03:49 【问题描述】:

我有一个包含一堆列的文件,其中一个名为 jsonstring 的列是字符串类型,其中包含 json 字符串……假设格式如下:


    "key1": "value1",
    "key2": 
        "level2key1": "level2value1",
        "level2key2": "level2value2"
    

我想像这样解析这个列:jsonstring.key1,jsonstring.key2.level2key1 to return value1, level2value1

如何在 scala 或 spark sql 中做到这一点。

【问题讨论】:

【参考方案1】:

在 Spark 2.2 中,您可以使用函数 from_json 为您解析 JSON。

from_json(e: Column, schema: String, options: Map[String, String]): Column 将包含 JSON 字符串的列解析为 StructTypeArrayType 的 @987654324 @ 具有指定的架构。

通过使用*(星号)支持展平嵌套列,这似乎是最佳解决方案。

// the input dataset (just a single JSON blob)
val jsonstrings = Seq("""
    "key1": "value1",
    "key2": 
        "level2key1": "level2value1",
        "level2key2": "level2value2"
    
""").toDF("jsonstring")

// define the schema of JSON messages
import org.apache.spark.sql.types._
val key2schema = new StructType()
  .add($"level2key1".string)
  .add($"level2key2".string)
val schema = new StructType()
  .add($"key1".string)
  .add("key2", key2schema)
scala> schema.printTreeString
root
 |-- key1: string (nullable = true)
 |-- key2: struct (nullable = true)
 |    |-- level2key1: string (nullable = true)
 |    |-- level2key2: string (nullable = true)

val messages = jsonstrings
  .select(from_json($"jsonstring", schema) as "json")
  .select("json.*") // <-- flattening nested fields
scala> messages.show(truncate = false)
+------+---------------------------+
|key1  |key2                       |
+------+---------------------------+
|value1|[level2value1,level2value2]|
+------+---------------------------+

scala> messages.select("key1", "key2.*").show(truncate = false)
+------+------------+------------+
|key1  |level2key1  |level2key2  |
+------+------------+------------+
|value1|level2value1|level2value2|
+------+------------+------------+

【讨论】:

【参考方案2】:

你可以使用 withColumn + udf + json4s:

import org.json4s.DefaultFormats, MappingException
import org.json4s.jackson.JsonMethods._
import org.apache.spark.sql.functions._

def getJsonContent(jsonstring: String): (String, String) = 
    implicit val formats = DefaultFormats
    val parsedJson = parse(jsonstring)  
    val value1 = (parsedJson \ "key1").extract[String]
    val level2value1 = (parsedJson \ "key2" \ "level2key1").extract[String]
    (value1, level2value1)

val getJsonContentUDF = udf((jsonstring: String) => getJsonContent(jsonstring))

df.withColumn("parsedJson", getJsonContentUDF(df("jsonstring")))

【讨论】:

谢谢,这很有帮助...有没有人有一些 sn-p 来处理异常...例如如果 key2 不存在,它会失败..我想处理它,只是说没有找到或类似的东西......我相信它微不足道,我可以弄清楚但如果有人得到 sn-p 会很好有它;)

以上是关于如何从json字符串中提取值?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 swift 从 JSON 中提取数据

使用 Python 从 JSON 嵌套列表和字符串数组中提取值

PHP:如何从字符串转储中提取 JSON 字符串

如何从 BigQuery 中的 JSON 字符串中提取数组

如何从配置单元表中的json字符串中提取数组元素?

需要从 json 字符串中提取属性和值