从 json 数组中按键获取值
Get value by key from json array
我有几个json数组
[{"key":"country","value":"aaa"},{"key":"region","value":"a"},{"key":"city","value":"a1"}]
[{"key":"city","value":"b"},{"key":"street","value":"1"}]
我需要将城市和街道值提取到不同的列中。
使用 get_json_object($"address", "$[2].value").as("city")
通过编号获取元素不起作用,因为数组可能会遗漏某些字段。
相反,我决定将此数组转换为键 -> 值对的映射,但在执行时遇到了麻烦。到目前为止,我只设法得到一个数组数组。
val schema = ArrayType(StructType(Array(
StructField("key", StringType),
StructField("value", StringType)
)))
from_json($"address", schema)
Returns
[[country, aaa],[region, a],[city, a1]]
[[city, b],[street, 1]]
我不知道从这里到哪里去。
val schema = ArrayType(MapType(StringType, StringType))
失败
cannot resolve 'jsontostructs(`address`)' due to data type mismatch: Input schema array<map<string,string>> must be a struct or an array of structs.;;
我正在使用 spark 2.2
使用 UDF 我们可以轻松处理这个问题。在下面的代码中,我使用 UDF 创建了一个地图。我希望这能满足需要
import org.apache.spark.sql.types._
import org.apache.spark.sql.functions._
val df1 = spark.read.format("text").load("file path")
val schema = ArrayType(StructType(Array(
StructField("key", StringType),
StructField("value", StringType)
)))
val arrayToMap = udf[Map[String, String], Seq[Row]] {
array => array.map { case Row(key: String, value: String) => (key, value) }.toMap
}
val dfJSON = df1.withColumn("jsonData",from_json(col("value"),schema))
.select("jsonData").withColumn("address", arrayToMap(col("jsonData")))
.withColumn("city", when(col("address.city").isNotNull, col("address.city")).otherwise(lit(""))).withColumn("street", when(col("address.street").isNotNull, col("address.street")).otherwise(lit("")))
dfJSON.printSchema()
dfJSON.show(false)
我有几个json数组
[{"key":"country","value":"aaa"},{"key":"region","value":"a"},{"key":"city","value":"a1"}]
[{"key":"city","value":"b"},{"key":"street","value":"1"}]
我需要将城市和街道值提取到不同的列中。
使用 get_json_object($"address", "$[2].value").as("city")
通过编号获取元素不起作用,因为数组可能会遗漏某些字段。
相反,我决定将此数组转换为键 -> 值对的映射,但在执行时遇到了麻烦。到目前为止,我只设法得到一个数组数组。
val schema = ArrayType(StructType(Array(
StructField("key", StringType),
StructField("value", StringType)
)))
from_json($"address", schema)
Returns
[[country, aaa],[region, a],[city, a1]]
[[city, b],[street, 1]]
我不知道从这里到哪里去。
val schema = ArrayType(MapType(StringType, StringType))
失败
cannot resolve 'jsontostructs(`address`)' due to data type mismatch: Input schema array<map<string,string>> must be a struct or an array of structs.;;
我正在使用 spark 2.2
使用 UDF 我们可以轻松处理这个问题。在下面的代码中,我使用 UDF 创建了一个地图。我希望这能满足需要
import org.apache.spark.sql.types._
import org.apache.spark.sql.functions._
val df1 = spark.read.format("text").load("file path")
val schema = ArrayType(StructType(Array(
StructField("key", StringType),
StructField("value", StringType)
)))
val arrayToMap = udf[Map[String, String], Seq[Row]] {
array => array.map { case Row(key: String, value: String) => (key, value) }.toMap
}
val dfJSON = df1.withColumn("jsonData",from_json(col("value"),schema))
.select("jsonData").withColumn("address", arrayToMap(col("jsonData")))
.withColumn("city", when(col("address.city").isNotNull, col("address.city")).otherwise(lit(""))).withColumn("street", when(col("address.street").isNotNull, col("address.street")).otherwise(lit("")))
dfJSON.printSchema()
dfJSON.show(false)