Мне нужно создать искровой dataframe из вложенного файла JSON в Scala - PullRequest
0 голосов
/ 22 января 2019

У меня есть файл Json, который выглядит следующим образом

{
  "tags": [
    {
      "1": "NpProgressBarTag",
      "2": "userPath",
      "3": "screen",
      "4": 6,
      "12": 9,
      "13": "buttonName",
      "16": 0,
      "17": 10,
      "18": 5,
      "19": 6,
      "20": 1,
      "35": 1,
      "36": 1,
      "37": 4,
      "38": 0,
      "39": "npChannelGuid",
      "40": "npShowGuid",
      "41": "npCategoryGuid",
      "42": "npEpisodeGuid",
      "43": "npAodEpisodeGuid",
      "44": "npVodEpisodeGuid",
      "45": "npLiveEventGuid",
      "46": "npTeamGuid",
      "47": "npLeagueGuid",
      "48": "npStatus",
      "50": 0,
      "52": "gupId",
      "54": "deviceID",
      "55": 1,
      "56": 0,
      "57": "uiVersion",
      "58": 1,
      "59": "deviceOS",
      "60": 1,
      "61": 0,
      "62": "channelLineupID",
      "63": 2,
      "64": "userProfile",
      "65": "sessionId",
      "66": "hitId",
      "67": "actionTime",
      "68": "seekTo",
      "69": "seekFrom",
      "70": "currentPosition"
    }
  ]
}

Я пытался создать фрейм данных, используя

val path = "some/path/to/jsonFile.json"
val df = sqlContext.read.json(path)
df.show()

, когда я запускаю это, я получаю

df: org.apache.spark.sql.DataFrame = [_corrupt_record: string]

Как создать df на основе содержимого ключа «tags»?все, что мне нужно, это вытащить данные из «тегов» и применить класс case как это

case class ProgLang (id: String, type: String )

Мне нужно преобразовать эти данные json в dataframe с именами двух столбцов.какой-то свет на эту ошибку?

Ответы [ 3 ]

0 голосов
/ 23 января 2019
val path = "some/path/to/jsonFile.json"
spark.read
  .option("multiLine", true).option("mode", "PERMISSIVE")
  .json(path)
0 голосов
/ 23 января 2019

попробуйте следующий код, если ваш файл JSON не очень большой

    val spark = SparkSession.builder().getOrCreate()
    val df = spark.read.json(spark.sparkContext.wholeTextFiles("some/path/to/jsonFile.json").values)
0 голосов
/ 23 января 2019

Вы можете изменить JSON, используя Circe .

Учитывая, что ваши значения иногда Строки и другие времена Числа , это было довольно сложно.

import io.circe._, io.circe.parser._, io.circe.generic.semiauto._

val json = """ ... """ // your JSON here.
val doc = parse(json).right.get
val mappedDoc = doc.hcursor.downField("tags").withFocus { array =>
  array.mapArray { jsons =>
    jsons.map { json =>
      json.mapObject { o =>
        o.mapValues { v =>
          // Cast numbers to strings.
          if (v.isString) v else Json.fromString(v.asNumber.get.toString)
        }
      }
    }
  }
}

final case class ProgLang(id: String, `type`: String )
final case class Tags(tags: List[Map[String, String]])
implicit val TagsDecoder: Decoder[Tags] = deriveDecoder

val tags = mappedDoc.top.get.as[Tags]
val data = for {
  tag <- res29.tags
  (id, _type) <- tag
} yield ProgLang(id, _type)

Теперь у вас есть список ProgLang, вы можете создать DataFrame непосредственно из него, сохранить его как файл с каждым JSON в строке, сохраните его как CSV файл и т. д. ...
Если файл очень большой, вы можете использовать fs2 для потоковой передачипри преобразовании он интегрируется красиво с Circe .


ОТКАЗ ОТ ОТВЕТСТВЕННОСТИ: Я далекоиз-за того, что он «профессионал» в Circe, это кажется слишком сложным для выполнения чего-то, что кажется «простой задачей», возможно, есть лучший / более чистый способ сделать это (возможно, с помощью оптики?), но эй!оно работает!- в любом случае, если кто-нибудь знает лучший способ решить эту проблему, не стесняйтесь редактировать вопрос или предоставить свой .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...