spark scala数据集联合数据集[Array [String]]

时间:2018-04-04 09:27:31

标签: scala apache-spark

我有两个Dataset[Array[String]]

第一个数据集有

之类的记录
8473245,0vqt141w2d6xfmsd1,c32d6691d56d27269d8d46e7e1caf950,p
11117398,0vqt141w3c57bb1b1,c32d6691d56d27269d8d46e7e1caf950,p
329726,1141556550,c0e85ebe26e6befa568502a3c7265c34,p
601438,1149608959,ab0e30f4d904d7f6dfbd48ff7ea955d5,p

另一个包含

等记录的数据集
8387081,0vqt141w7h6rwq9b1,c32d6691d56d27269d8d46e7e1caf950,p
1194736,1243752711,c0e85ebe26e6befa568502a3c7265c34,p

现在我想要一个包含第一个数据集中所有记录的数据集 并且只有第二个数据集中第二个数据集与第一个数据集匹配的记录。结果数据集应该有记录:

8473245,0vqt141w2d6xfmsd1,c32d6691d56d27269d8d46e7e1caf950,p
11117398,0vqt141w3c57bb1b1,c32d6691d56d27269d8d46e7e1caf950,p
329726,1141556550,c0e85ebe26e6befa568502a3c7265c34,p
601438,1149608959,ab0e30f4d904d7f6dfbd48ff7ea955d5,p
8387081,0vqt141w7h6rwq9b1,c32d6691d56d27269d8d46e7e1caf950,p

1 个答案:

答案 0 :(得分:1)

由于您在数据中没有标题行,我认为您正在阅读以下数据(我已经使用了一个第二列匹配用于测试目的

val dataset1 = sqlContext.read.option("header", false).csv("file1 path")
val dataset2 = sqlContext.read.option("header", false).csv("file2 path")

应该给你

dataset1
+--------+-----------------+--------------------------------+---+
|_c0     |_c1              |_c2                             |_c3|
+--------+-----------------+--------------------------------+---+
|8473245 |0vqt141w2d6xfmsd1|c32d6691d56d27269d8d46e7e1caf950|p  |
|11117398|0vqt141w3c57bb1b1|c32d6691d56d27269d8d46e7e1caf950|p  |
|329726  |1141556550       |c0e85ebe26e6befa568502a3c7265c34|p  |
|601438  |1149608959       |ab0e30f4d904d7f6dfbd48ff7ea955d5|p  |
+--------+-----------------+--------------------------------+---+

dataset2
+-------+-----------------+--------------------------------+---+
|_c0    |_c1              |_c2                             |_c3|
+-------+-----------------+--------------------------------+---+
|8387081|0vqt141w2d6xfmsd1|c32d6691d56d27269d8d46e7e1caf950|p  |
|1194736|1243752711       |c0e85ebe26e6befa568502a3c7265c34|p  |
+-------+-----------------+--------------------------------+---+

以下解决方案适合您(注释为解释

//dataset2 columns to be selected
val columnsToSelect = dataset2.columns

//joining and selecting matching rows
import org.apache.spark.sql.functions._
val matchingDataset2 = dataset1.as("table1").join(dataset2.as("table2"), col("table1._c1") === col("table2._c1"))
  .select(columnsToSelect.map(x => col("table2."+x)): _*)

//merging matching dataset2 with dataset1
dataset1.union(matchingDataset2)

应该给你

+--------+-----------------+--------------------------------+---+
|_c0     |_c1              |_c2                             |_c3|
+--------+-----------------+--------------------------------+---+
|8473245 |0vqt141w2d6xfmsd1|c32d6691d56d27269d8d46e7e1caf950|p  |
|11117398|0vqt141w3c57bb1b1|c32d6691d56d27269d8d46e7e1caf950|p  |
|329726  |1141556550       |c0e85ebe26e6befa568502a3c7265c34|p  |
|601438  |1149608959       |ab0e30f4d904d7f6dfbd48ff7ea955d5|p  |
|8387081 |0vqt141w2d6xfmsd1|c32d6691d56d27269d8d46e7e1caf950|p  |
+--------+-----------------+--------------------------------+---+

我希望答案很有帮助

更新

您已发表评论

  
    

有没有办法将org.apache.spark.sql.Dataset [org.apache.spark.sql.Row]转换为数据集[Array(String)]

  

您可以调用地图功能并根据需要更改数据

dataset1.union(matchingDataset2)
  .map(row => row.toSeq.map(_.toString))
//org.apache.spark.sql.Dataset[Seq[String]] = [value: array<string>]