val items = List("a", "b", "c")
sqlContext.sql("select c1 from table")
.filter($"c1".isin(items))
.collect
.foreach(println)
Le code ci-dessus lève l'exception suivante.
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)
Ci-dessous ma tentative de le réparer. Il compile et s'exécute mais ne renvoie aucune correspondance. Pas certain de pourquoi.
val items = List("a", "b", "c").mkString("\"","\",\"","\"")
sqlContext.sql("select c1 from table")
.filter($"c1".isin(items))
.collect
.foreach(println)
Selon la documentation, isin
prend un vararg, pas une liste. La liste est en fait un nom déroutant ici. Vous pouvez essayer de convertir votre liste en vararg comme ceci:
val items = List("a", "b", "c")
sqlContext.sql("select c1 from table")
.filter($"c1".isin(items:_*))
.collect
.foreach(println)
Votre variante avec mkString est compilée, car une seule chaîne est également une variable (avec un nombre d'arguments égal à 1), mais ce n'est pas ce que vous voulez réaliser.
Cela a fonctionné comme ceci dans Java Api (Java 8)
.isin(sampleListName.stream().toArray(String[]::new))));
sampleListName est une liste
Encore plus facile:
sqlContext.sql("select c1 from table")
.filter($"c1".isin("a", "b", "c"))
.collect
.foreach(println)
Sauf si vous avez beaucoup de valeurs de liste, ce n'est généralement pas le cas.