2015-09-13 15 views
30
val items = List("a", "b", "c") 

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

Mã ở trên ném ngoại lệ sau đây.Bộ lọc tia lửa không hoạt động như mong đợi

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) 

Dưới đây là nỗ lực của tôi để khắc phục sự cố. Nó biên dịch và chạy nhưng không trả về bất kỳ kết quả nào. Không chắc chắn lý do tại sao.

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

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

Theo [tài liệu] (https://spark.apache.org/docs/latest/ api/java/org/apache/spark/sql/Column.html # isin (java.lang.Object ...)) 'isin' lấy danh sách chứ không phải chuỗi. – Tomalak

Trả lời

57

Theo tài liệu, isin mất một vararg, không phải là một danh sách. Danh sách thực sự là một cái tên khó hiểu ở đây. Bạn có thể thử chuyển đổi Danh sách của bạn để vararg như thế này:

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

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

biến thể của bạn với mkString biên dịch, vì một chuỗi đơn cũng là một vararg (với số lượng đối số bằng 1), nhưng nó là proably không phải những gì bạn muốn để đạt được.

+0

wow, đó là một bummer khó hiểu. Tôi đã nhận thấy điều này trong một loạt các nơi trong Spark. varargs có vẻ khá an toàn vì nó được chỉ định là Any. Làm thế nào chúng ta có thể khắc phục điều này?! – nont

+0

cuối cùng tôi đã làm việc này! chỉ cần rằng: _ * điều haha ​​cảm ơn! –

+0

@không bạn cuối cùng đã tìm ra lý do tại sao Spark hút. Xin chúc mừng! – piggybox

-1

Như Tomalak đã đề cập đến nó:

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. 

Do đó, bạn chỉ có thể khắc phục điều này làm cho sự thay đổi sau đây:

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

Tại sao lại là bản đồ? My là '.filter ($" c1 ".isin (Danh sách (" a "," b "," c ")))' sẽ hoạt động. – Tomalak

+0

Xem xét mã của bạn 'Danh sách (" a "," b "," c "). MkString (" \ "", "\", \ "", "\" ")', tôi giả định rằng bạn muốn bao quanh mỗi mục bằng dấu ngoặc kép. Bản đồ cũng làm như vậy. –

+0

Không phải mã của tôi. ;) – Tomalak

3

Nó làm việc như thế này trong Java Api (Java 8)

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

sampleListName là một danh sách

Các vấn đề liên quan