【问题标题】:Java + Apache Spark inner join between two datesets两个数据集之间的 Java + Apache Spark 内连接
【发布时间】:2022-01-04 07:32:44
【问题描述】:

请教关于如何使用 Apache Spark 和 Java 实现内部连接的小问题。

我有这段非常简单的代码。

final Dataset<Row> dataSetTableLeft = getDatasetForLeft();
final Dataset<Row> dataSetTableRight = getDatasetForRight();
final Dataset<Row> dataSetTableResult = dataSetTableLeft.join(dataSetTableRight);

dataSetTableLeft.show();
dataSetTableRight.show();
dataSetTableResult.show();

第一张表dataSetTableLeft.show ,长这样,很直观。

+----------+-----+
|      time|label|
+----------+-----+
|1637020800|    0|
|1637107200|    0|
|1637193600|    0|
|1637280000|    0|
|1637366400|    0|
|1637452800|    0|
+----------+-----+"

第二张表dataSetTableRight,长这样,也很直观。

+----------+-----+
|      time|label|
+----------+-----+
|1637193600|    1|
|1637280000|    2|
|1637366400|    1|
+----------+-----+"

我想要实现的是这样一个结果表,它是一种内连接。

+----------+-----+
|      time|label|
+----------+-----+
|1637020800|    0|
|1637107200|    0|
|1637193600|    1|
|1637280000|    2|
|1637366400|    1|
|1637452800|    0|
+----------+-----+"

不幸的是,我没有看到任何这样的功能。 innerjoin()

因此,我正在尝试某种组合

dataSetTableLeft.unionAll(dataSetTableRight);
dataSetTableLeft.crossJoin(dataSetTableRight);

到目前为止没有任何运气。

实现内连接的正确方法是什么?

【问题讨论】:

    标签: java apache-spark apache-spark-sql


    【解决方案1】:

    内连接只会为您提供两个数据集中存在的行。您在这里想要的是保留dataSetTableLeft 中的所有行,并在time 匹配时从dataSetTableRight 检索label 值。

    为此,只需在匹配时使用左连接和coalesce 函数从第二个数据集中获取label 值。

    以下是提供数据的完整工作示例:

    import static org.apache.spark.sql.functions.*;
    
    dataSetTableLeft.show();
    //+----------+-----+
    //|      time|label|
    //+----------+-----+
    //|1637020800|    0|
    //|1637107200|    0|
    //|1637193600|    0|
    //|1637280000|    0|
    //|1637366400|    0|
    //|1637452800|    0|
    //+----------+-----+
    
    dataSetTableRight.show();
    //+----------+-----+
    //|      time|label|
    //+----------+-----+
    //|1637193600|    1|
    //|1637280000|    2|
    //|1637366400|    1|
    //+----------+-----+
    
    
    dataSetTableLeft.alias("df1").join(
            dataSetTableRight.alias("df2"),
            dataSetTableLeft.col("time").equalTo(dataSetTableRight.col("time")),
            "left_outer"
    ).select(
            dataSetTableLeft.col("time"),
            expr("coalesce(df2.label, df1.label)").alias("label")
    ).show();
    
    //+----------+-----+
    //|      time|label|
    //+----------+-----+
    //|1637020800|    0|
    //|1637107200|    0|
    //|1637193600|    1|
    //|1637280000|    2|
    //|1637366400|    1|
    //|1637452800|    0|
    //+----------+-----+
    

    【讨论】:

    • 您好@blackbishop,非常感谢您的回答。我已经尝试过你的 sn-p,它正在产生另一个结果。结果是列时间的所有键,值为 2,然后值为 1。 1637020800 2 - 1637020800 1 - 1637107200 2 - 1637107200 1 - 1637193600 2 - 1637193600 1 等等。请问我做错了什么吗?
    • @PatPatPat 您好,我不确定我是否理解您的问题。我使用您问题中提供的数据添加了一个完整的示例。请查看我编辑的问题。
    • 有了新的sn-p,我可以得到想要的结果。感谢您布置所有的 sn-p,它非常有帮助。这是正确的解决方案,赞成+接受。美好的一天!
    猜你喜欢
    • 2019-06-06
    • 2019-01-27
    • 1970-01-01
    • 2017-08-16
    • 2023-03-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-08
    相关资源
    最近更新 更多