优化Spark Scala上的where请求

时间:2018-12-25 15:12:43

标签: scala apache-spark

我是Apache Spark(和Scala)的新手,我想在读取csv文件并将其加载到DF之后立即应用一个简单的sql请求,而无需创建其他数据框或临时视图或表。< / p>

这是最初的请求:

SELECT DISTINCT city from cities
WHERE id IN ("10", "20")
AND year IN ("2017", "2018")

这是我在Scala上尝试过的:

val cities = spark.read.options(Map("header" -> "true", "delimiter" -> ";")).csv("test.csv").select("city").distinct.where(""" id IN ("10", "20") AND year IN ("2017", "2018")"""))

cities.show(20)

但是它不起作用。具体来说,似乎是由于无法识别数据框中的其他两列而导致出现此问题(因为我之前只选择了一列)。因此,我必须首先选择这三列,然后保存一个临时表(视图),然后在新数据框中选择所需的列。我发现这种方法太长太重。

您能帮我解决这个问题吗??? 谢谢!

3 个答案:

答案 0 :(得分:1)

您的解决方案几乎是正确的,您只需要将where语句移到select(..).distinct之前:

val cities = spark.read
  .options(Map("header" -> "true", "delimiter" -> ";"))
  .csv("test.csv")
  .where($"id".isin("10", "20") and $"year".isin("2017", "2018"))
  .select("city").distinct

答案 1 :(得分:0)

Spark scala API比声明性命令更重要(与SQL不同),这就是为什么在select("city")之后丢失数据帧中所有其他字段的原因。以及其他人指出的原因,在进行选择之前,应先过滤/位置。这有点令人困惑,因为Scala DSL的语法类似于SQL

答案 2 :(得分:0)

如sramalingam24和Raphael Roth所述,在从DataFrame中选择所需字段之前,必须先应用where。过滤器和两者都给出相同的结果,如下所示。 dropDuplicates()将删除城市列中的重复项。

    val cities = spark.read.options(Map("header" -> "true", "delimiter" -> ";"))
       .csv("test.csv")
       .filter($"id".isin("10", "20") and $"year".isin("2017", "2018"))
       .select("city")
       .dropDuplicates()