Фильтр искры isin не работает должным образом
val items = List("a", "b", "c")
sqlContext.sql("select c1 from table")
.filter($"c1".isin(items))
.collect
.foreach(println)
Приведенный выше код выдает следующее исключение.
Exception in thread "main" java.lang.RuntimeException: Unsupported literal type class scala.collection.immutable.$colon$colon List(a, b, c)
at org.apache.spark.sql.catalyst.expressions.Literal$.apply(literals.scala:49)
at org.apache.spark.sql.functions$.lit(functions.scala:89)
at org.apache.spark.sql.Column$$anonfun$isin$1.apply(Column.scala:642)
at org.apache.spark.sql.Column$$anonfun$isin$1.apply(Column.scala:642)
at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:245)
at scala.collection.TraversableLike$$anonfun$map$1.apply(TraversableLike.scala:245)
at scala.collection.IndexedSeqOptimized$class.foreach(IndexedSeqOptimized.scala:33)
at scala.collection.mutable.WrappedArray.foreach(WrappedArray.scala:35)
at scala.collection.TraversableLike$class.map(TraversableLike.scala:245)
at scala.collection.AbstractTraversable.map(Traversable.scala:104)
at org.apache.spark.sql.Column.isin(Column.scala:642)
Ниже моя попытка исправить это. Он компилируется и запускается, но не возвращает никакого соответствия. Не знаю, почему.
val items = List("a", "b", "c").mkString("\"","\",\"","\"")
sqlContext.sql("select c1 from table")
.filter($"c1".isin(items))
.collect
.foreach(println)
Ответы
Ответ 1
Согласно документации, isin
принимает vararg, а не список. Список на самом деле представляет собой запутанное имя. Вы можете попробовать преобразовать свой список в vararg следующим образом:
val items = List("a", "b", "c")
sqlContext.sql("select c1 from table")
.filter($"c1".isin(items:_*))
.collect
.foreach(println)
Ваш вариант с mkString компилируется, потому что одна единственная String также является vararg (с числом аргументов, равным 1), но это не то, чего вы хотите достичь.
Ответ 2
Он работал так, как в Java Api (Java 8)
.isin(sampleListName.stream().toArray(String[]::new))));
sampleListName - это список
Ответ 3
Как сказал Томалак:
isin(java.lang.Object... list)
A boolean expression that is evaluated to true if the value
of this expression is contained by the evaluated values of the arguments.
Поэтому вы можете исправить это, сделав следующее изменение:
val items = List("a", "b", "c").map(c => s""""$c"""")