Как разобрать JSON, содержащий строковое свойство, представляющее JSON

У меня есть много 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

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
356
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Все, что вам нужно сделать, это проанализировать строку 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)

Можно ли использовать JavaScript в записной книжке Databricks?

Jon 05.04.2019 18:39

Извините, я не знаком, что это такое

Lelouch 05.04.2019 18:46

эй, ребята, это не проблема разобрать в целом, как это сделать с помощью Spark Data Frame API?

Alex S 05.04.2019 22:06

N1v1 также доступен таким образом, нет, я не знаю, что это такое, можете ли вы объяснить, чего именно вы пытаетесь достичь?

Lelouch 05.04.2019 22:29

Когда вы извлекаете элемент «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 (т.е. удалить символы выхода "\"), повторно создав его, как показано выше.

Joey Morrow 05.04.2019 18:44

в общем разобрать не проблема, как это сделать с API Spark Data Frame?

Alex S 05.04.2019 22:06
Ответ принят как подходящий

Один из подходов — использовать 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 |
+--------------+--------------+---------------------+---+---+---+

Пожалуйста, дайте мне знать, если вам нужны дополнительные разъяснения.

Большое спасибо. Это именно то, что я искал!

Alex S 08.04.2019 09:37

Другие вопросы по теме

Фильтрация кадров данных, обусловленных несколькими столбцами, с различными условиями в зависимости от значений столбца
Динамически зацикливать набор данных для всех имен столбцов
Как получить данные второго фрейма данных для всех значений определенных значений столбцов, совпадающих в первом фрейме данных?
Как сравнить две таблицы и заменить нули значениями из другой таблицы
Как наилучшим образом преобразовать столбец SparkSQL Dataframe Array[String] в новый столбец [String]
Искровое соединение, вызывающее ошибку неоднозначности идентификатора столбца
Sql-запрос без использования в нем внутреннего соединения
Ошибка сводки Spark DF: сводка метода ([класс java.lang.String, класс java.lang.String]) не существует
Сравнение двух столбцов Dataframe и отображение результата, который доступен в df1, а не в df2
Искра scala создает столбец из Dataframe со значениями, зависящими от диапазона дат и времени

Похожие вопросы

Фильтрация кадров данных, обусловленных несколькими столбцами, с различными условиями в зависимости от значений столбца
Динамически зацикливать набор данных для всех имен столбцов
Как получить данные второго фрейма данных для всех значений определенных значений столбцов, совпадающих в первом фрейме данных?
Как сравнить две таблицы и заменить нули значениями из другой таблицы
Как построить график из фрейма данных? (ГрафикX)
Конфигурация для задания искры для записи файла 3000000 в качестве вывода
Если мы создадим несколько сеансов Spark с помощью метода newSession(), как будет распределяться память драйвера между несколькими сеансами Spark?
Как мне написать автономное приложение в Spark, чтобы найти 20 самых упоминаний в текстовом файле, заполненном извлеченными твитами
Местоположение динамического пути AWS Glue Crawl S3
Сбой UDF Apache Spark Python