簡體   English   中英

加入spark后有效統計記錄

[英]Effectively counting records after join in spark

這就是我正在做的。 我需要獲取一個數據集中存在的記錄數,而不是另一個數據集,然后再次加入第三個數據集以獲取其他一些列。

val tooCompare = dw
        .select(
          "loc",
          "id",
          "country",
          "region"
        ).dropDuplicates()

val previous = dw
        .select(
          "loc",
          "id",
          "country",
          "region"
        ).dropDuplicates()

val delta = tooCompare.exceptAll(previous).cache()
 
val records = delta
        .join(
          dw,//another dataset
          delta
            .col("loc").equalTo(dw.col("loc"))
            .and(delta.col("id").equalTo(dw.col("id")))
            .and(delta.col("country").equalTo(dw.col("country")))
            .and(delta.col("region").equalTo(dw.col("region")))
        )
        .drop(delta.col("loc"))
        .drop(delta.col("id"))
        .drop(delta.col("country"))
        .drop(delta.col("region"))
        .cache()
    }

 val recordsToSend = records.cache()
 val count = recordsToSend.select("loc").distinct().count()

有沒有更有效的方法來做到這一點? 我是 Spark 的新手。 我很確定我在這里遺漏了一些東西

我建議使用 SQL 使其更具可讀性。

首先,創建相關數據幀的臨時視圖。 不知道你有什么數據幀,所以像

dfToCompare.createOrReplaceTempView("toCompare")
previousDf.createOrReplaceTempView("previous")
anotherDataSet.createOrReplaceTempView("another")

然后,您可以繼續在一條 SQL 語句中完成所有操作

val records = spark.sql("""select loc, id, country,region
              from toCompare c
              inner join another a
               on a.loc = c.loc  
                and a.id = p.id
                and a.country = c.country
                and a.region = c.region
             where not exists (select null
                                from previous p
                                where p.loc = c.loc  
                                 and p.id = p.id
                                 and p.country = c.country
                                 and p.region = c.region""")

然后你可以像以前一樣繼續......

val recordsToSend = records.cache()
val count = recordsToSend.select("loc").distinct().count()

我認為您粘貼的代碼中可能存在一些錯誤,因為 tooCompare 和以前的代碼相同,+ 第三個數據集連接引用了 deAnon 但表上的 dw ....

對於此示例答案,假設您的當前表稱為“當前”,前一個稱為“上一個”,第三個表稱為“額外”。 然后:

val delta = current.join(
              previous, 
              Seq("loc","id","country","region"), 
              "leftanti"
            ).select("loc","id","country","region").distinct

val recordsToSend = delta
                    .join(
                      extra,
                      Seq("loc", "id", "country", "region")
                    )

val count = recordsToSend.select("loc").distinct().count()

這可能更有效,但我很感激你評論它是否真的有效!

順便說一句:請注意,我使用 Seq[String] 作為連接參數(這要求兩個表上的列名相同,並且不會生成列的兩個副本)。 但是,您的原始連接邏輯可以寫得更簡潔一些,如下(使用我的命名約定):

val recordsToSend = delta
                    .join(
                      extra,
                      delta("loc") === extra("loc")
                        && delta("id") === extra("id")
                        && delta("country") === extra("country")
                        && delta("region") === extra("region")
                    )
                    .drop(delta("loc"))
                    .drop(delta("id"))
                    .drop(delta("country"))
                    .drop(delta("region"))

更好的是編寫一個 drop 函數,讓您提供多個列,但我現在真的離題了 ;-)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM