У меня есть много JSON со следующей структурой.
{
"p1":"v1",
"p2":"v2",
"p3":"v3",
"modules": "{ \"nest11\":\"n1v1\", \"nest12\":\"n1v2\", \"nest13\": { \"nest21\": \"n2v1\" } }"
}
Как это разобрать?
v1, v2, v3, n1v1, n1v2, n2v1
Не проблема извлечь "v1, v2, v3", но как получить доступ к "n1v1, n1v2, n2v1" С API фрейма данных Spark





Все, что вам нужно сделать, это проанализировать строку JSON для фактического объекта javascript.
const originalJSON = {
"p1":"v1",
"p2":"v2",
"p3":"v3",
"modules": "{ \"nest11\":\"n1v1\", \"nest12\":\"n1v2\", \"nest13\": { \"nest21\": \"n2v1\" } }"
}
const { modules, ...rest } = originalJSON
const result = {
...rest,
modules: JSON.parse(modules)
}
console.info(result)
console.info(result.modules.nest11)
Извините, я не знаком, что это такое
эй, ребята, это не проблема разобрать в целом, как это сделать с помощью Spark Data Frame API?
N1v1 также доступен таким образом, нет, я не знаю, что это такое, можете ли вы объяснить, чего именно вы пытаетесь достичь?
Когда вы извлекаете элемент «modules», вы фактически извлекаете строку. Вы должны создать эту строку как новый объект JSON. Я не знаю, какой язык вы используете, но обычно вы делаете что-то вроде:
String modules_str = orginalJSON.get("modules");
JSON modulesJSON = new JSON(modules_str);
String nest11_str = modulesJSON.get("nest11");
Идея состоит в том, что дважды закодированный JSON хранится в виде строки в родительской структуре JSON. Неизвестно, что он закодирован JSON, кроме вас, кодировщика/декодера. Поскольку вы знать это JSON, вы можете преобразовать его обратно в структуру JSON (т.е. удалить символы выхода "\"), повторно создав его, как показано выше.
в общем разобрать не проблема, как это сделать с API Spark Data Frame?
Один из подходов — использовать DataFrameFlattener неявный класс нашел на официальном сайте блоков данных.
Сначала вам нужно будет определить схему JSON для столбца модули, а затем сгладить фрейм данных, как показано ниже. Здесь я предполагаю, что файл test_json.txt
будет иметь следующее содержание:
{
"p1":"v1",
"p2":"v2",
"p3":"v3",
"modules": "{ \"nest11\":\"n1v1\", \"nest12\":\"n1v2\", \"nest13\": { \"nest21\": \"n2v1\" } }"
}
Вот код:
import org.apache.spark.sql.functions.col
import org.apache.spark.sql.{Column, DataFrame}
import org.apache.spark.sql.types.{DataType, StructType, StringType}
implicit class DataFrameFlattener(df: DataFrame) {
def flattenSchema: DataFrame = {
df.select(flatten(Nil, df.schema): _*)
}
protected def flatten(path: Seq[String], schema: DataType): Seq[Column] = schema match {
case s: StructType => s.fields.flatMap(f => flatten(path :+ f.name, f.dataType))
case other => col(path.map(n => s"`$n`").mkString(".")).as(path.mkString(".")) :: Nil
}
}
val schema = (new StructType)
.add("nest11", StringType)
.add("nest12", StringType)
.add("nest13", (new StructType).add("nest21", StringType, false))
val df = spark.read
.option("multiLine", true).option("mode", "PERMISSIVE")
.json("C:\\temp\\test_json.txt")
df.withColumn("modules", from_json($"modules", schema))
.select($"*")
.flattenSchema
И это должно быть на выходе:
+--------------+--------------+---------------------+---+---+---+
|modules.nest11|modules.nest12|modules.nest13.nest21|p1 |p2 |p3 |
+--------------+--------------+---------------------+---+---+---+
|n1v1 |n1v2 |n2v1 |v1 |v2 |v3 |
+--------------+--------------+---------------------+---+---+---+
Пожалуйста, дайте мне знать, если вам нужны дополнительные разъяснения.
Большое спасибо. Это именно то, что я искал!
Можно ли использовать JavaScript в записной книжке Databricks?