Извлечение данных JSON в Spark / Scala - PullRequest
0 голосов
/ 18 октября 2018

У меня есть файл json с этой структурой

root
 |-- labels: struct (nullable = true)
 |    |-- compute.googleapis.com/resource_name: string (nullable = true)
 |    |-- container.googleapis.com/namespace_name: string (nullable = true)
 |    |-- container.googleapis.com/pod_name: string (nullable = true)
 |    |-- container.googleapis.com/stream: string (nullable = true)

Я хочу извлечь четыре .....googleapis.com/... в четыре столбца.

Я пробовал это:

import org.apache.spark.sql.functions._
df = df.withColumn("resource_name", df("labels.compute.googleapis.com/resource_name"))
       .withColumn("namespace_name", df("labels.compute.googleapis.com/namespace_name"))
       .withColumn("pod_name", df("labels.compute.googleapis.com/pod_name"))
       .withColumn("stream", df("labels.compute.googleapis.com/stream"))

Я также попытался сделать это, сделав labels массив, который решил первую ошибку, в которой говорится, что подуровни не являются array или map

df2 = df.withColumn("labels", explode(array(col("labels"))))   
        .select(col("labels.compute.googleapis.com/resource_name").as("resource_name"), col("labels.compute.googleapis.com/namespace_name").as("namespace_name"), col("labels.compute.googleapis.com/pod_name").as("pod_name"), col("labels.compute.googleapis.com/stream").as("stream"))

Я все еще получаю эту ошибку

org.apache.spark.sql.AnalysisException: No such struct field compute in compute.googleapis.com/resource_name .....

Я знаю, Spark считает, что каждая точка является вложенным уровнем, но как я могу отформатировать compute.googleapis.com/resource_name, который spark распознает как имя уровня, а не многоуровневый.

Я также пытался решить, как указано здесь

Как заставить Apache искру игнорировать точки в запросе?

Но это также не решило мою проблему.У меня есть label.compute.googleapis.com/resource_name, добавление обратных галочек к compute.googleapis.com/resource_name по-прежнему выдает ту же ошибку.

Ответы [ 2 ]

0 голосов
/ 22 октября 2018

Переименовав столбцы (или подуровни), затем выполните withColumn

val schema = """struct<resource_name:string, namespace_name:string, pod_name:string, stream:string>"""
val df1 = df.withColumn("labels", $"labels".cast(schema))
0 голосов
/ 19 октября 2018

Вы можете использовать обратный апостроф `, чтобы изолировать имена, содержащие специальные символы, такие как '. '.Вы должны использовать backtick после меток , так как это родительский тег.

val extracted = df.withColumn("resource_name", df("labels.`compute.googleapis.com/resource_name`"))
    .withColumn("namespace_name", df("labels.`container.googleapis.com/namespace_name`"))
    .withColumn("pod_name", df("labels.`container.googleapis.com/pod_name`"))
    .withColumn("stream", df("labels.`container.googleapis.com/stream`"))

  extracted.show(10, false)

Вывод:

+--------------------+-------------+--------------+--------+------+
|labels              |resource_name|namespace_name|pod_name|stream|
+--------------------+-------------+--------------+--------+------+
|[RN_1,NM_1,PM_1,S_1]|RN_1         |NM_1          |PM_1    |S_1   |
+--------------------+-------------+--------------+--------+------+

ОБНОВЛЕНИЕ 1 Полныйрабочий пример.

import org.apache.spark.sql.functions._
val j_1 =
  """
    |{ "labels" : {
    |   "compute.googleapis.com/resource_name" : "RN_1",
    |   "container.googleapis.com/namespace_name" : "NM_1",
    |   "container.googleapis.com/pod_name" : "PM_1",
    |   "container.googleapis.com/stream" : "S_1"
    |             }
    |}
  """.stripMargin

  val df = spark.read.json(Seq(j_1).toDS)
  df.printSchema()

  val extracted = df.withColumn("resource_name", df("labels.`compute.googleapis.com/resource_name`"))
    .withColumn("namespace_name", df("labels.`container.googleapis.com/namespace_name`"))
    .withColumn("pod_name", df("labels.`container.googleapis.com/pod_name`"))
    .withColumn("stream", df("labels.`container.googleapis.com/stream`"))

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