Spark Scala - объединить столбец в строках в определенном порядке - PullRequest
0 голосов
/ 28 августа 2018

Хорошо, у меня есть таблица с определениями столбцов и соответствующими порядковыми позициями. Я строю управляемую метаданными ETL-фреймворк, используя Spark (scala). У меня есть таблица, которая содержит следующую информацию:

  • имя_таблица
  • имя столбца
  • Тип данных
  • ordinalposition

Я должен построить оператор CREATE TABLE из этих данных. Ничего страшного, правда? Я попробовал то, что кажется стандартным ответом:

var metadatadef = spark.sql("SELECT tablename, columnname, datatype, ordinalposition FROM metadata")
    .withColumn("columndef", concat($"columnname", lit(" "), $"datatype"))
    .sort($"tablename", $"ordinalposition")
    .groupBy("tablename")
    .agg(concat_ws(", ", collect_list($"columndef")).as("columndefs"))

Но вызов sort () здесь, похоже, игнорируется. Или между collect_list () и concat_ws () он перетасовывается. Приведенные исходные данные, как это:

+-----------+--------------+---------------+-----------------+
| tablename | columnname   | datatype      | ordinalposition |
+ ----------+--------------+---------------+-----------------+
| table1    | IntColumn    | int           | 0               |
| table2    | StringColumn | string        | 2               |
| table1    | StringColumn | string        | 2               |
| table2    | IntColumn    | int           | 0               |
| table1    | DecColumn    | decimal(15,2) | 1               |
| table2    | DecColumn    | decimal(15,2) | 1               |
+-----------+--------------+---------------+-----------------+

Я пытаюсь получить вывод, подобный этому:

+-----------+----------------------------------------------------------------+
| tablename | columndefs                                                     |
+-----------+----------------------------------------------------------------+
| table1    | IntColumn int, DecColumn decimal(15,2), StringColumn string    |
| table2    | IntColumn int, DecColumn decimal(15,2), StringColumn string    |
+-----------+----------------------------------------------------------------+

Вместо этого я получаю что-то вроде этого:

+-----------+----------------------------------------------------------------+
| tablename | columndefs                                                     |
+-----------+----------------------------------------------------------------+
| table1    | IntColumn int, StringColumn string, DecColumn decimal(15,2)    |
| table2    | StringColumn string, IntColumn int, DecColumn decimal(15,2)    |
+-----------+----------------------------------------------------------------+

Нужно ли создавать UDF, чтобы убедиться, что я получаю правильный заказ? Мне нужно, чтобы выходные данные оказались в кадре данных для целей сравнения, а не просто для создания оператора CREATE TABLE.

1 Ответ

0 голосов
/ 28 августа 2018

Вы можете создать столбец struct (ordinalposition, columndef) и применить sort_array для сортировки агрегированного columndef в требуемом порядке во время преобразования groupBy следующим образом:

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

val df = Seq(
  ("table1", "IntColumn", "int", "0"),
  ("table2", "StringColumn", "string", "2"),
  ("table1", "StringColumn", "string", "2"),
  ("table2", "IntColumn", "int", "0"),
  ("table1", "DecColumn", "decimal(15,2)", "1"),
  ("table2", "DecColumn", "decimal(15,2)", "1")
).toDF("tablename", "columnname", "datatype", "ordinalposition")

df.
  withColumn("columndef",
    struct($"ordinalposition", concat($"columnname", lit(" "), $"datatype").as("cdef"))
  ).
  groupBy("tablename").agg(sort_array(collect_list($"columndef")).as("sortedlist")).
  withColumn("columndefs", concat_ws(", ", $"sortedlist.cdef")).
  drop("sortedlist").
  show(false)
// +---------+-----------------------------------------------------------+
// |tablename|columndefs                                                 |
// +---------+-----------------------------------------------------------+
// |table2   |IntColumn int, DecColumn decimal(15,2), StringColumn string|
// |table1   |IntColumn int, DecColumn decimal(15,2), StringColumn string|
// +---------+-----------------------------------------------------------+
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...