Как запросить вложенный тип массива json-файла с помощью Spark? - PullRequest
0 голосов
/ 20 декабря 2018

Как я могу запросить вложенный тип массива, используя объединения, используя набор данных Spark?

В настоящее время я анализирую тип массива и выполняю объединение в наборе данных, где мне нужно удалить совпадающие данные.Но есть ли способ, при котором я могу напрямую запросить его без взрыва.

{
  "id": 525,
  "arrayRecords": [
    {
      "field1": 525,
      "field2": 0
    },
    {
      "field1": 537,
      "field2": 1
    }
  ]
}

Код

val df = sqlContext.read.json("jsonfile")
val someDF = Seq(("1"),("525"),("3")).toDF("FIELDIDS")
val withSRCRec =df.select($"*",explode($"arrayRecords")as("exploded_arrayRecords"))
val fieldIdMatchedDF= withSRCRec.as("table1").join(someDF.as("table2"),$"table1.exploded_arrayRecords.field1"===$"table2.FIELDIDS").select($"table1.exploded_arrayRecords.field1")

val finalDf = df.as("table1").join(fieldIdMatchedDF.as("table2"),$"table1.id"===$"table2.id","leftanti")

Идентификационные записи, имеющие fieldIds, должны быть удалены

Ответы [ 2 ]

0 голосов
/ 21 декабря 2018

Вместо этого можно использовать array_except:

array_except (col1: Column, col2: Column): Column Возвращает массив элементов в первом массиве, но нево втором массиве, без дубликатов.Порядок элементов в результате не определен

Решение может быть следующим:

val input = spark.read.option("multiLine", true).json("input.json")
scala> input.show(false)
+--------------------+---+
|arrayRecords        |id |
+--------------------+---+
|[[525, 0], [537, 1]]|525|
+--------------------+---+

// Since field1 is of type int, let's convert the ids to ints
// You could do this in Scala directly or in Spark SQL's select
val fieldIds = Seq("1", "525", "3").toDF("FIELDIDS").select($"FIELDIDS" cast "int")

// Collect the ids for array_except
val ids = fieldIds.select(collect_set("FIELDIDS") as "ids")

// The trick is to crossJoin (it is cheap given 1-row ids dataset)
val solution = input
  .crossJoin(ids)
  .select(array_except($"arrayRecords.field1", $"ids") as "unmatched")
scala> solution.show
+---------+
|unmatched|
+---------+
|    [537]|
+---------+
0 голосов
/ 20 декабря 2018

Вы можете зарегистрировать временную таблицу на основе вашего набора данных и запросить ее с помощью SQL.Это было бы что-то вроде этого:

someDs.registerTempTable("sometable");
sql("SELECT array['field'] FROM sometable");
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...