Vraag Hoe Column.isin te gebruiken met een lijst?


val items = List("a", "b", "c")

sqlContext.sql("select c1 from table")
          .filter($"c1".isin(items))
          .collect
          .foreach(println)

De bovenstaande code genereert de volgende uitzondering.

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)

Hieronder is mijn poging om het te repareren. Het compileert en wordt uitgevoerd, maar retourneert geen enkele overeenkomst. Niet zeker waarom.

val items = List("a", "b", "c").mkString("\"","\",\"","\"")

sqlContext.sql("select c1 from table")
          .filter($"c1".isin(items))
          .collect
          .foreach(println)

35
2017-09-13 16:32


oorsprong


antwoorden:


Volgens documentatie, isin neemt een vararg, geen lijst. Lijst is hier eigenlijk een verwarrende naam. U kunt proberen uw lijst te converteren naar vararg als volgt:

val items = List("a", "b", "c")

sqlContext.sql("select c1 from table")
          .filter($"c1".isin(items:_*))
          .collect
          .foreach(println)

Uw variant met mkString compileert, omdat een enkele String ook een vararg is (met een aantal argumenten gelijk aan 1), maar het is waarschijnlijk niet wat u wilt bereiken.


66
2017-09-14 08:19



Het werkte als volgt in Java Api (Java 8)

.isin(sampleListName.stream().toArray(String[]::new))));

sampleListName is een lijst


6
2017-09-09 17:55



Zoals Tomalak het heeft genoemd:

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.

Daarom kunt u dit probleem oplossen door de volgende wijziging aan te brengen:

val items = List("a", "b", "c").map(c => s""""$c"""")

-1
2017-09-13 16:45