如何拆分和合并记录?

时间:2017-06-26 19:31:54

标签: apache-spark apache-spark-sql

我有一个CSV文件,customer_id的数据如下所示。

CUSTID,LOC,PRODNAME,UNITS,TYPE,PURCHASE_DATE
123,"SA","PROD1",1000,"PAY","20-DEC-2016"
123,"SA","PROD2",500,"REC","31-AUG-2016"

这必须转换为三个记录,一个作为父记录,另外两个作为基于TYPE列的子记录,如下所示。这必须最终进入另一个CSV文件。

ROWTYPE,CUSTID,LOC,TYPE,PRODUCT_NAME,UNITS,PURCHASE_DATE
PARENT,123,"SA"
CHILD,123,"SA","PAY","PROD1","20-DEC-2016"
CHILD,123,"SA","REC","PROD2","31-AUG-2016"

同一任务还有两件事。

  1. 我的输出CSV文件只有一个标题,仅用于父记录,子记录可以包含比父记录更多或更少的字段。 由于这个原因,我不能UNION父和子,所以我只是将所有的数据帧转换为RDD并在那上做了一个联合。 所以要知道,如果必须使用Dataframes完成,我该怎么做?

  2. 最后,我需要根据CUSTID和TYPE字段以某种特定顺序创建CSV文件。我知道这很容易引入Dataframes,但是因为我将它们转换为RDD,我做了以下但不知道它是否是一种最佳方法。

  3. 当我按照排序进行重新分区并合并输出CSV文件时,即使这个也不起作用。

1 个答案:

答案 0 :(得分:1)

使用PARENT,123,"SA"进行简单查询即可轻松获得groupBy

val parents = customers.
  select(lit("PARENT") as "ROWTYPE", $"custid", $"loc").
  dropDuplicates
scala> parents.show
+-------+------+---+
|ROWTYPE|custid|loc|
+-------+------+---+
| PARENT|   123| SA|
+-------+------+---+

有了这个,你union与其他人一起获得最终的PARENTCHILD记录。

由于union只能在列数相同的表上执行,customers有6列且parents有3列,因此必须使数据集匹配。< / p>

val fullParents = parents.
  withColumn("PRODUCT_NAME", lit("")).
  withColumn("UNITS", lit("")).
  withColumn("TYPE", lit("")).
  withColumn("PURCHASE_DATE", lit(""))
scala> .show
+-------+------+---+------------+-----+----+-------------+
|ROWTYPE|custid|loc|PRODUCT_NAME|UNITS|TYPE|PURCHASE_DATE|
+-------+------+---+------------+-----+----+-------------+
| PARENT|   123| SA|            |     |    |             |
+-------+------+---+------------+-----+----+-------------+

我们将ROWTYPE添加为CHILD customers

val rowtypedCustomers = customers.
  select(lit("CHILD") as "ROWTYPE", customers("*")).
  withColumnRenamed("PRODNAME", "PRODUCT_NAME")
scala> rowtypedCustomers.show
+-------+------+---+------------+-----+----+-------------+
|ROWTYPE|CUSTID|LOC|PRODUCT_NAME|UNITS|TYPE|PURCHASE_DATE|
+-------+------+---+------------+-----+----+-------------+
|  CHILD|   123| SA|       PROD1| 1000| PAY|  20-DEC-2016|
|  CHILD|   123| SA|       PROD2|  500| REC|  31-AUG-2016|
+-------+------+---+------------+-----+----+-------------+

val solution = fullParents.union(rowtypedCustomers)
scala> .show
+-------+------+---+------------+-----+----+-------------+
|ROWTYPE|custid|loc|PRODUCT_NAME|UNITS|TYPE|PURCHASE_DATE|
+-------+------+---+------------+-----+----+-------------+
| PARENT|   123| SA|            |     |    |             |
|  CHILD|   123| SA|       PROD1| 1000| PAY|  20-DEC-2016|
|  CHILD|   123| SA|       PROD2|  500| REC|  31-AUG-2016|
+-------+------+---+------------+-----+----+-------------+

将其写为CSV就像以下查询一样简单:

solution.write.csv("solution.csv")

完成。 恭喜!