Scala 在Spark DataFrame的列中搜索字符串的最佳方法

Scala 在Spark DataFrame的列中搜索字符串的最佳方法,scala,apache-spark,apache-spark-sql,Scala,Apache Spark,Apache Spark Sql,我正在使用ApacheSpark2.2和Scala2.11 我有一个字符串,我从中创建1-gram、2-gram和3-gram。之后,我尝试在数据帧中搜索这些值。现在这个过程发生了很多次,因为整个Spark工作需要很多时间。我该怎么想呢 以下是代码片段: // creating the n-grams val vNGrams = for (i <- 1 to 3) yield sampleString.trim.split(" ").sliding(i).map(p => p.mkS

我正在使用ApacheSpark2.2和Scala2.11

我有一个字符串,我从中创建1-gram、2-gram和3-gram。之后,我尝试在数据帧中搜索这些值。现在这个过程发生了很多次,因为整个Spark工作需要很多时间。我该怎么想呢

以下是代码片段:

// creating the n-grams
val vNGrams = for (i <- 1 to 3) yield sampleString.trim.split(" ").sliding(i).map(p => p.mkString(" "))  

// converting them to a single array as above code generates three different iterators for different ngrams
val z = vNGrams.map(itr => itr.toArray).flatten.toArray

for (i <- 0 to z.length-1) {
  val df = vSomeTable.select("COUNTRY_CODE").where(upper(col("ZIPCODE")) === z(i).toUpperCase)
  if(df.count.toInt > 0) {
    countryCode = df.take(1)(0)(0).toString
    return countryCode
  }
}
//创建n-grams
val vNGrams=for(i p.mkString(“”)
//如上所述,将它们转换为单个数组,代码会为不同的NGRAM生成三个不同的迭代器
valz=vNGrams.map(itr=>itr.toArray).flatten.toArray
对于(i 0){
countryCode=df.take(1)(0)(0).toString
返回国家代码
}
}
在Spark UI中,我可以看到这些
count
take
作业需要时间。此代码段至少运行了20k次,而且
vSomeTable
是一个具有41k行的数据帧


如果您需要更多信息,请告诉我,或者我可以用更少的时间以不同的方式完成相同的工作。

请取消for循环,改用单个作业,而不是多个Spark作业。另外,避免同时使用
df.count
df.take
limit 1
以避免提前退出

val z = vNGrams.flatten.map(_.toUpperCase).toArray

val rows = vSomeTable
  .select("COUNTRY_CODE")
  .where(upper(col("ZIPCODE")).isInCollection(z))
  .limit(1)
  .collect()
if (!rows.isEmpty) {
  ...
}


isInCollection
来自spark 2.4,我使用的是2.2。我应该使用什么函数来代替它呢?@GadaaDhaariGeek
isInCollection
仅仅是一个方便的包装器,用于
isin(z:*)
,它从1.5.0开始就可以使用。是的,我仅从网络上了解到这一点。不管怎样,谢谢。但问题还是一样。现在,
collect()。获取行后,我要做的是将COUNTRY_代码作为字符串返回。这方面有什么帮助吗?听起来不错,
collect
是应该花费时间的地方,可以说它比原始版本快。由于存在
limit 1
,因此可能最容易将国家/地区代码收集到
选项[String]
so
…limit(1)。选择($“国家/地区代码”).collect().collectFirst{case Row(cc:String)=>cc}