java.NullPointException 在 DataFrame.show() 方法中的 spark - scala
java.NullPointException in DataFrame.show() method in spark - scala
编辑:对之前的问题质量感到抱歉,我希望这个问题会更清楚:
使用 Spark 应用程序,我正在加载以下 JSON 个文件的整个目录:
{
"type": "some_type",
"payload": {
"data1": {
"id": "1"
},
"data2": {
"id": "1",
},
"data3": {
"id": "1"
},
"dataset1": [{
"data11": {
"id": "1",
},
"data12": {
"id": "1",
}
}],
"masterdata": {
"md1": [{
"id": "1"
},
{
"id": "2"
},
{
"id": "3"
}],
"md2": [{
"id": "1",
},
{
"id": "2",
},
{
"id": "3",
}]
}
}
}
到 DataFrame
并保存为临时文件 table 以便以后使用。在此 Json 中,来自 "payload" 节点的字段始终存在,但 "masterdata" 中的子节点是可选的。
下一步是为 Json 的每个子节点创建多个数据帧,如下所示:
DataFrame data1 包含来自所有文件的节点 "data1" 的数据,看起来像一个带有列 "id" 的常规 table。
在第一次处理部分后,我的 Spark 状态如下:
数据框:
数据 1(id),
数据 2(id),
数据 3(id),
数据 11(id),
数据 12(id),
md1(id),
md2(id)
问题来了 - 如果目录中的 JSON 文件之一不包含 md2 节点,我无法 运行 show()
或 collect()
"md2" DataFrame 由于 NullPointException。
我会理解是否所有文件都缺少 "md2" 节点,所以它无法创建 md2 DataFrame,但在这种情况下,我希望 md2 DataFrame 根本没有来自没有节点 md2 的 json 文件的数据,但是包含所有其他人。
技术细节:
要从嵌套节点读取数据,我使用 rdd.map & rdd.flatmap,然后我将其转换为 DataFrame
并使用自定义列名称
如果我 运行 在目录中的所有文件包含所有节点时应用程序一切正常,但如果缺少单个文件 md2 节点应用程序在 .show() 或 .collect() 时失败
顺便说一句,如果节点存在但它为空则一切正常。
有没有办法让 Spark 支持可选的 Json 节点或处理 rdd.map&flatmap 中丢失的节点?[=18=]
我希望它比上一个问题更清楚
根据@Beryllium 的请求,这是我用来获取 md2 DataFrame 的 rdd 操作
val jsonData = hiveContext.sql("SELECT `payload`.masterdata.md2 FROM jsonData")
val data = jsonData.rdd.flatMap(row => row.getSeq[Row](0)).map(row => (
row.getString(row.fieldIndex("id"))
)).distinct
val dataDF = data.toDF("id")
快速修复
尝试像这样插入 filter()
:
sqlContext.sql("SELECT payload.masterdata.md2 FROM jsonData")
.rdd
.filter(_.getSeq[Row](0) != null)
.flatMap(row => row.getSeq[Row](0))
.map(row => (row.getString(row.fieldIndex("id"))))
.distinct
.toDF("id")
.show()
使用爆炸()
这会尽快删除空值:所以它应该更快(至少更短):
sqlContext
.sql("select t.a.id from (SELECT explode(payload.masterdata.md2) as a FROM jsonData) t")
explode()
炸掉 null
.
- 然后子查询只提取ID
更简单:先提取ID,然后explode()
:
sqlContext.sql("SELECT explode(payload.masterdata.md2.id) FROM jsonData").show()
编辑:对之前的问题质量感到抱歉,我希望这个问题会更清楚: 使用 Spark 应用程序,我正在加载以下 JSON 个文件的整个目录:
{
"type": "some_type",
"payload": {
"data1": {
"id": "1"
},
"data2": {
"id": "1",
},
"data3": {
"id": "1"
},
"dataset1": [{
"data11": {
"id": "1",
},
"data12": {
"id": "1",
}
}],
"masterdata": {
"md1": [{
"id": "1"
},
{
"id": "2"
},
{
"id": "3"
}],
"md2": [{
"id": "1",
},
{
"id": "2",
},
{
"id": "3",
}]
}
}
}
到 DataFrame
并保存为临时文件 table 以便以后使用。在此 Json 中,来自 "payload" 节点的字段始终存在,但 "masterdata" 中的子节点是可选的。
下一步是为 Json 的每个子节点创建多个数据帧,如下所示:
DataFrame data1 包含来自所有文件的节点 "data1" 的数据,看起来像一个带有列 "id" 的常规 table。
在第一次处理部分后,我的 Spark 状态如下:
数据框:
数据 1(id),
数据 2(id),
数据 3(id),
数据 11(id),
数据 12(id),
md1(id),
md2(id)
问题来了 - 如果目录中的 JSON 文件之一不包含 md2 节点,我无法 运行 show()
或 collect()
"md2" DataFrame 由于 NullPointException。
我会理解是否所有文件都缺少 "md2" 节点,所以它无法创建 md2 DataFrame,但在这种情况下,我希望 md2 DataFrame 根本没有来自没有节点 md2 的 json 文件的数据,但是包含所有其他人。
技术细节:
要从嵌套节点读取数据,我使用 rdd.map & rdd.flatmap,然后我将其转换为 DataFrame
并使用自定义列名称
如果我 运行 在目录中的所有文件包含所有节点时应用程序一切正常,但如果缺少单个文件 md2 节点应用程序在 .show() 或 .collect() 时失败
顺便说一句,如果节点存在但它为空则一切正常。
有没有办法让 Spark 支持可选的 Json 节点或处理 rdd.map&flatmap 中丢失的节点?[=18=]
我希望它比上一个问题更清楚
根据@Beryllium 的请求,这是我用来获取 md2 DataFrame 的 rdd 操作
val jsonData = hiveContext.sql("SELECT `payload`.masterdata.md2 FROM jsonData")
val data = jsonData.rdd.flatMap(row => row.getSeq[Row](0)).map(row => (
row.getString(row.fieldIndex("id"))
)).distinct
val dataDF = data.toDF("id")
快速修复
尝试像这样插入 filter()
:
sqlContext.sql("SELECT payload.masterdata.md2 FROM jsonData")
.rdd
.filter(_.getSeq[Row](0) != null)
.flatMap(row => row.getSeq[Row](0))
.map(row => (row.getString(row.fieldIndex("id"))))
.distinct
.toDF("id")
.show()
使用爆炸()
这会尽快删除空值:所以它应该更快(至少更短):
sqlContext
.sql("select t.a.id from (SELECT explode(payload.masterdata.md2) as a FROM jsonData) t")
explode()
炸掉null
.- 然后子查询只提取ID
更简单:先提取ID,然后explode()
:
sqlContext.sql("SELECT explode(payload.masterdata.md2.id) FROM jsonData").show()