Scala 发送Row.empty时在Spark结构化流中获取ArrayIndexOutOfBounds异常
我是一个名为Scala 发送Row.empty时在Spark结构化流中获取ArrayIndexOutOfBounds异常,scala,apache-spark,apache-spark-sql,spark-structured-streaming,Scala,Apache Spark,Apache Spark Sql,Spark Structured Streaming,我是一个名为test的卡夫卡主题,我在其中发送字符串消息。之后,我通过Spark结构化流媒体根据某些条件过滤这些消息。像这样: scala> val df = spark.readStream.format("kafka").option("kafka.bootstrap.servers", "localhost:9092").option("startingOffsets", "earliest").option("subscribe", "test") df: org.apache.s
test
的卡夫卡主题,我在其中发送字符串消息。之后,我通过Spark结构化流媒体根据某些条件过滤这些消息。像这样:
scala> val df = spark.readStream.format("kafka").option("kafka.bootstrap.servers", "localhost:9092").option("startingOffsets", "earliest").option("subscribe", "test")
df: org.apache.spark.sql.streaming.DataStreamReader = org.apache.spark.sql.streaming.DataStreamReader@6ff87203
scala> import org.apache.spark.sql.types._
import org.apache.spark.sql.types._
scala> val schema = StructType(StructField("message", StringType) :: Nil)
schema: org.apache.spark.sql.types.StructType = StructType(StructField(message,StringType,true))
scala> val data = df.load().select(from_json(col("value").cast("string"), schema).as("value"))
data: org.apache.spark.sql.DataFrame = [value: struct<message: string>]
scala> import org.apache.spark.sql.catalyst.encoders.RowEncoder
import org.apache.spark.sql.catalyst.encoders.RowEncoder
scala> implicit val encoder = RowEncoder(schema)
encoder: org.apache.spark.sql.catalyst.encoders.ExpressionEncoder[org.apache.spark.sql.Row] = class[message[0]: string]
scala> import org.apache.spark.sql.Row
import org.apache.spark.sql.Row
scala> val q = data.select("value.*").map(row => if(row.getString(0) == "hello") row else Row.empty)
q: org.apache.spark.sql.Dataset[org.apache.spark.sql.Row] = [message: string]
scala> q.writeStream.outputMode("append").format("console").start()
res0: org.apache.spark.sql.streaming.StreamingQuery = org.apache.spark.sql.execution.streaming.StreamingQueryWrapper@7ef3b7ac
我无法理解为什么在这里出现ArrayIndexOutOfBounds
异常。如果数据是空的,那么我应该得到一个空的DataFrame/Dataset
,而不是一个异常
这是预期的行为吗?这里的问题是
行。空的表示没有列的行。在代码中,您告诉Spark行架构是StructType(StructField(“message”,StringType)::Nil)
,因此不应返回row.empty
。相反,您应该返回Row(null)
,这是一个具有null
列的行。这里的问题是Row。empty
表示没有列的行。在代码中,您告诉Spark行架构是StructType(StructField(“message”,StringType)::Nil)
,因此不应返回row.empty
。相反,您应该返回Row(null)
,这是一个具有null
列的行。我也遇到了同样的问题,只是在有人发现有用时共享
如果您的数据帧没有架构中的所有列,那么它将抛出此错误
rows.scala->
override def get(i: Int): Any = values(i)
i
是架构中当前字段的索引。您试图从行中获取i
th字段,但该字段没有,因此出现异常
只需为该模式属性添加一个值(如果模式允许,也可以为null)就可以解决问题。我也遇到过同样的问题,只是在有人发现它有用时共享
如果您的数据帧没有架构中的所有列,那么它将抛出此错误
rows.scala->
override def get(i: Int): Any = values(i)
i
是架构中当前字段的索引。您试图从行中获取i
th字段,但该字段没有,因此出现异常
只需为该模式属性添加一个值(如果模式允许,也可以为null)即可解决此问题