Чтение JSON с ведущей отметкой времени - PullRequest
0 голосов
/ 02 июля 2019

У меня есть набор данных (~ 100 ГБ) в S3, который имеет метку времени, за которой следует строка JSON, а не просто строка JSON.Эти данные распакованы.Есть ли способ прочитать эти данные в Dataframe без переформатирования данных для удаления метки времени?Мне вообще не нужна временная метка, ее можно не принимать во внимание.Вот пример данных:

2019-06-28T00:00:00.000Z { "a": 123, "b": "456", "c": 789 }

Обычно я использую библиотеку клея read_from_options для чтения данных, но я не вижу возможности игнорировать метку времени и просто читать в строке JSON,Я не был уверен, что у Spark Hand есть какая-либо функциональность для этого.

Ответы [ 2 ]

3 голосов
/ 02 июля 2019

Ответ Anamdeo - хороший, но я хотел бы подчеркнуть, что вам следует избегать использования UDF, когда это возможно, из-за проблем с производительностью.В этом случае вы можете легко использовать regexp_extract для отделения метки времени от интересующего вас контента JSON:

scala> val regex =  "([0-9\\-TZ\\.:]+) (\\{.*)"
regex: String = ([0-9\-TZ\.:]+) (\{.*)

scala> val dff = df.withColumn("tstamp", regexp_extract('json_content, regex, 1)).withColumn("json", regexp_extract('json_content, regex, 2)).drop("json_content")
dff: org.apache.spark.sql.DataFrame = [country: string, city: string ... 2 more fields]

scala> dff.show(false)
+-------+-------+------------------------+----------------------------------+
|country|city   |tstamp                  |json                              |
+-------+-------+------------------------+----------------------------------+
|america|chicago|2019-06-28T00:00:00.000Z|{ "a": 123, "b": "456", "c": 789 }|
|india  |mumbai |2019-06-28T00:00:00.000Z|{ "a": 123, "b": "456", "c": 789 }|
+-------+-------+------------------------+----------------------------------+

С этого момента вы можете использовать встроенные функции Spark, такие как from_json и get_json_object для непосредственной работы с данными JSON при необходимости.

3 голосов
/ 02 июля 2019

Предположим, вот как выглядят данные -

country|city|json_content
america|chicago|2019-06-28T00:00:00.000Z { "a": 123, "b": "456", "c": 789 }
india|mumbai|2019-06-28T00:00:00.000Z { "a": 123, "b": "456", "c": 789 }

Считать их в искровой фрейм данных -

    val df = spark
      .read
      .option("header", "true") // Use first line of all files as header
      .option("delimiter", "|")
      .csv("csv_file_path")

Поскольку вы уже распаковали данные, сначала прочитайте их в СДРкак показано ниже, затем преобразуйте его в DF ( Дайте мне знать, если вам нужна моя помощь в преобразовании RDD в DF. ) -

val rdd = sc.textFile("myFile.gz")

Импортважные функции -

import org.apache.spark.sql.functions._

Напишите и зарегистрируйте UDF, который извлекает только содержимое json из вашей метки времени + столбец json

    val getJsonContent = udf{input: String => input.substring(input.indexOf("{"))}

Примените этот UDF и создайте окончательный Dataframe-

    val finalDf = df.withColumn("json_content",getJsonContent(col("json_content")))
...