sparksql(“< some aggregate query>”).first().getdouble(0)提供不一致的结果

efzxgjgh  于 2021-06-26  发布在  Hive
关注(0)|答案(2)|浏览(350)

我有下面的查询,它应该找到列值的平均值,并返回我的结果,这是一个单一的数字。

val avgVal = hiveContext.sql("select round(avg(amount), 4) from users.payment where dt between '2018-05-09' and '2018-05-09'").first().getDouble(0)

我面对的是不一致的行为。这通常会失败并出现以下错误,但在通过配置单元执行时,它会给出非空结果。”

18/05/10 11:01:12 ERROR ApplicationMaster: User class threw exception: java.lang.NullPointerException: Value at index 0 in null
java.lang.NullPointerException: Value at index 0 in null
    at org.apache.spark.sql.Row$class.getAnyValAs(Row.scala:475)
    at org.apache.spark.sql.Row$class.getDouble(Row.scala:243)
    at org.apache.spark.sql.catalyst.expressions.GenericRow.getDouble(rows.scala:192)

我使用hivecontext而不是sqlcontext的原因是后者不支持我在代码中广泛使用的一些聚合函数。
你能帮我理解为什么会出现这个问题以及如何解决吗?

pbgvytdp

pbgvytdp1#

您需要将查询分成两部分:

var result = hiveContext.sql("select round(avg(amount), 4) from users.payment where dt between '2018-05-09' and '2018-05-09'");
var first = result.first();
if (first != null && !first.isNullAt(0)) {
var avgVal = first.getDouble(0);
}

这样可以避免npe。这在列表和数组中也是需要的。
对于insert或update查询,您甚至需要 try...catch 块以捕获运行时异常。

ekqde3dh

ekqde3dh2#

让我们分析一下抛出此异常的情况和可能的原因。

Row row = hiveContext.sql("select info, name, desc, id from users.payment where dt between '2018-05-09' and '2018-05-09'").first();

如果 row 上面是这样的:

[null, Kevin, cash, 300]

试图得到 getDouble(0) 将导致 java.lang.NullPointerException: Value at index 0 in null 您可以尝试以下方法:

Row row = hiveContext.sql("select round(avg(amount), 4) from users.payment where dt between '2018-05-09' and '2018-05-09'").first();

if (!row.isNullAt(0))
   double d = row.getDouble(0);
else
   logger.error("Value at index zero is null");

如果要检查源代码,库类将执行相反的操作:

private static Object getAnyValAs(Row $this, int i) {
    if($this.isNullAt(i)) {
        throw new NullPointerException((new StringContext(scala.Predef..MODULE$.wrapRefArray((Object[])(new String[]{"Value at index ", " is null"})))).s(scala.Predef..MODULE$.genericWrapArray(new Object[]{BoxesRunTime.boxToInteger(i)})));
    } else {
        return $this.getAs(i);
    }
}

相关问题