Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/apache-spark/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala—当Row.get(i)检索空值时,如何避免java.lang.IllegalArgumentException_Scala_Apache Spark_Parquet - Fatal编程技术网

Scala—当Row.get(i)检索空值时,如何避免java.lang.IllegalArgumentException

Scala—当Row.get(i)检索空值时,如何避免java.lang.IllegalArgumentException,scala,apache-spark,parquet,Scala,Apache Spark,Parquet,我正在使用Spark和Scala阅读一些拼花文件。我面临的问题是,这个拼花地板文件的内容可能会有所不同,即某些字段有时不存在。因此,当我尝试访问文件中不存在的字段时,会出现以下异常: java.lang.IllegalArgumentException:字段“ErrorHeaderIndicator”不存在 不存在 我曾经在Java中做过类似的事情,可以使用contains()或get(index)!=null检查我们试图访问的字段是否存在。但我在Scala不能做到同样的事情 下面你可以看到我迄

我正在使用Spark和Scala阅读一些拼花文件。我面临的问题是,这个拼花地板文件的内容可能会有所不同,即某些字段有时不存在。因此,当我尝试访问文件中不存在的字段时,会出现以下异常:

java.lang.IllegalArgumentException:字段“ErrorHeaderIndicator”不存在 不存在

我曾经在Java中做过类似的事情,可以使用
contains()
get(index)!=null
检查我们试图访问的字段是否存在。但我在Scala不能做到同样的事情

下面你可以看到我迄今为止写的东西和我尝试过的四件事,但都没有成功

//The part of reading the parquet file and accessing the rows works fine
val sqlContext = new org.apache.spark.sql.SQLContext(sc)
import sqlContext.implicits._

val parquetFileDF = sqlContext.read.parquet("myParquet.parquet')

//I get one of the six blocks in the parquet file
val myHeaderData = parquetFileDF.select("HeaderData").collectAsList()

//When I try to access a particular field which is not in the "HeaderData"
//I get the exception

//1st Try
Option(myHeaderData.get(0).getStruct(0).getAs[String]("wrongHeaderIndicator")) match {
      case Some(i) => println("This data exist")
      case None => println("This would be a null") 
}

//2nd Try
if(myHeaderData.get(0).getStruct(0).getAs[String]("wrongHeaderIndicator")!= null)
        println("This data exist")
    else
        println("This is null")

//3rd Try
println(myHeaderData.get(0).getStruct(0).fieldIndex("wrongHeaderIndicator"))

//4th Try
println(Some(myHeaderData.get(0).getStruct(0).getAs[String]("wrongHeaderIndicator")))
编辑问题不在于访问数据帧的列时。列总是相同的,我不需要在选择之前执行检查。当我访问特定列中记录的字段时,问题就出现了。这些记录是您可以在下面看到的架构:

列myHeaderData的架构类似于:

|-- myHeaderData: struct (nullable = true)
 |    |-- myOpIndicator: string (nullable = true)
 |    |-- mySecondaryFlag: string (nullable = true)
 |    |-- myDownloadDate: string (nullable = true)
 |    |-- myDownloadTime: string (nullable = true)
 |    |-- myUUID: string (nullable = true)
如果我跑

myHeaderData.get(0).getStruct(0).schema
我得到以下输出:

StructType(StructField(myOpIndicator,StringType,true), StructField(mySecondaryFlag,StringType,true), StructField(myDownloadDate,StringType,true), StructField(myDownloadTime,StringType,true), StructField(myUUID,StringType,true))

我尝试的四件事产生了相同的异常。有谁能告诉我,在不生成异常的情况下,我可以使用什么来检查结构中是否存在字段


谢谢

您可以轻松检查数据帧中是否存在列。使用
df.columns
方法获取包含数据中所有标题的数组,然后检查列(
ErrorHeaderIndicator
)是否在数组中。下面是一个简短的例子:

val df = Seq(("aaa", "123"), ("bbb", "456"), ("ccc", "789")).toDF("col1", "col2")
df.show()

+----+----+
|col1|col2|
+----+----+
| aaa| 123|
| bbb| 456|
| ccc| 789|
+----+----+

使用
df.columns.toList
现在将为您提供
列表(col1,col2)
。要检查字段是否存在,只需执行
df.columns.contains(“fieldName”)

即可轻松检查数据帧中是否存在列。使用
df.columns
方法获取包含数据中所有标题的数组,然后检查列(
ErrorHeaderIndicator
)是否在数组中。下面是一个简短的例子:

val df = Seq(("aaa", "123"), ("bbb", "456"), ("ccc", "789")).toDF("col1", "col2")
df.show()

+----+----+
|col1|col2|
+----+----+
| aaa| 123|
| bbb| 456|
| ccc| 789|
+----+----+

使用
df.columns.toList
现在将为您提供
列表(col1,col2)
。要检查您的字段是否存在,只需执行
df.columns.contains(“fieldName”)

您做出了错误的假设。如果
getAs
字段不存在,它将抛出异常,而不是返回
null
。因此,您应该使用
尝试

import scala.util.{Try, Success, Failure}
import org.apache.spark.sql.Row

val row: Row = spark.read.json(sc.parallelize(Seq(
  """{"myHeaderData": {"myOpIndicator": "foo"}}"""))).first

Try(row.getAs[Row]("myHeaderData").getAs[String]("myOpIndicator")) match {
  case Success(s) => println(s)
  case _ => println("error")
}

你的假设是错误的。如果
getAs
字段不存在,它将抛出异常,而不是返回
null
。因此,您应该使用
尝试

import scala.util.{Try, Success, Failure}
import org.apache.spark.sql.Row

val row: Row = spark.read.json(sc.parallelize(Seq(
  """{"myHeaderData": {"myOpIndicator": "foo"}}"""))).first

Try(row.getAs[Row]("myHeaderData").getAs[String]("myOpIndicator")) match {
  case Success(s) => println(s)
  case _ => println("error")
}

我想说的是,我确实在stackoverflow中查找过这个问题,但我找不到解决问题的方法。如果有人可以让我参考一个已经回答的问题,请将其添加到此评论中,我将自己结束此问题。似乎您正在尝试查找“错误标题指示器”并比较其输出。但您应该检查“错误标题指示器”本身是否存在。@Gabain1993是的。我怎样才能检查它是否正确exist@user8371915,没有。我知道如何检测数据表中是否有列。这里我想检查结构中是否有元素,我想说的是我在stackoverflow中已经找到了这个问题,但是我找不到解决问题的方法。如果有人可以让我参考一个已经回答的问题,请将其添加到此评论中,我将自己结束此问题。似乎您正在尝试查找“错误标题指示器”并比较其输出。但您应该检查“错误标题指示器”本身是否存在。@Gabain1993是的。我怎样才能检查它是否正确exist@user8371915,没有。我知道如何检测数据表中是否有列。这里我想检查的是结构中是否有元素。谢谢你的回复,但这部分在我发布的代码中已经解决了,myHeaderData已经是一个列了。问题在于下一步。每列有多条记录,每条记录是一个结构,可以包含1到5个字段。有时5个字段都存在,有时不存在。还有一件事,我正在做problems@IgnacioAlorre啊,我明白了。我一定是误解你了。你能给出一些结构的例子吗?谢谢你的回复,但这部分在我发布的代码中已经解决了,myHeaderData已经是一个列了。问题在于下一步。每列有多条记录,每条记录是一个结构,可以包含1到5个字段。有时5个字段都存在,有时不存在。还有一件事,我正在做problems@IgnacioAlorre啊,我明白了。我一定是误解你了。你能举一些结构的例子吗?谢谢。用Try{}而不是{}选项成功了,不再有例外。谢谢。Try{}而不是选项{}成功了,不再有例外。