2016-08-30 2 views
2

У меня есть файл, который имеет кучу колонок и один столбец jsonstring имеет строковый тип, который имеет JSon строки в нем ... скажем, формат выглядит следующим образом:Как извлечь значения из строки json?

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

Я хочу разобрать этот столбец что-то вроде это: jsonstring.key1, jsonstring.key2.level2key1 для возврата value1, level2value1

Как это сделать в scala или spark sql.

ответ

1

Вы можете использовать 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"))) 
+0

спасибо, что это было полезно ... есть ли у кого-нибудь фрагмент, чтобы справиться с этим исключением ... например, например. если key2 не существует, он не работает. Я хотел бы обработать его и просто сказать, что не нашел или что-то в этом роде ... Я уверен, что его тривиально, и я могу понять это, но будет полезно получить фрагмент, если у кого-то есть это ;) –

0

С Спарк 2.2 вы можете использовать функцию from_json с делает разборе JSON для вас.

from_json (е: Колонка, схема: String, опции: Map [String, String]): Колонка разбирает столбец, содержащий строку JSON в StructType или ArrayType из StructTypes с указанной схемой.

С поддержкой выравнивания вложенных столбцов с помощью * (звезда), который кажется лучшим решением.

// 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| 
+------+------------+------------+