对从JSON

时间:2018-02-25 12:52:52

标签: scala apache-spark apache-spark-sql

我正在处理由JSON创建的数据框,然后我想在数据框上应用过滤条件。

val jsonStr = """{ "metadata": [{ "key": 84896, "value": 54 },{ "key": 1234, "value": 12 }]}"""
val rdd = sc.parallelize(Seq(jsonStr))
val df = sqlContext.read.json(rdd)

df架构

root
 |-- metadata: array (nullable = true)
 |    |-- element: struct (containsNull = true)
 |    |    |-- key: long (nullable = true)
 |    |    |-- value: long (nullable = true)

现在我需要过滤我想要做的数据框

val df1=df.where("key == 84896")

引发错误

ERROR Executor - Exception in task 0.0 in stage 1.0 (TID 1)
org.apache.spark.sql.AnalysisException: cannot resolve '`key`' given input columns: [metadata]; line 1 pos 0;
'Filter ('key = 84896)

我想使用where子句的原因是因为我想直接使用的表达式字符串 例如( (key == 999, value == 55) || (key == 1234, value == 12) )

2 个答案:

答案 0 :(得分:1)

首先,您应该使用explode来获得易于使用的dataFrame。然后,您可以选择给定输入的键和值:

val explodedDF = df.withColumn("metadata", explode($"metadata"))
  .select("metadata.key", "metadata.value")

输出:

+-----+-----+
|  key|value|
+-----+-----+
|84896|   54|
| 1234|   12|
+-----+-----+

这样您就可以像往常一样执行过滤逻辑:

scala> explodedDF.where("key == 84896").show
+-----+-----+
|  key|value|
+-----+-----+
|84896|   54|
+-----+-----+

您可以连接过滤要求,以下是一些示例:

explodedDF.where("key == 84896 AND value == 54")
explodedDF.where("(key == 84896 AND value == 54) OR key = 1234")

答案 1 :(得分:0)

根据我对您的问题和评论的理解,您尝试应用( (key == 999, value == 55) || (key == 1234, value == 12) )表达式来过滤数据框行。

首先,表达式需要更改,因为它无法作为表达式应用于 spark 中的dataframe,因此您需要更改为

val expression = """( (key == 999, value == 55) || (key == 1234, value == 12) )"""
val actualExpression = expression.replace(",", " and").replace("||", "or")

应该为您提供新的有效表达式

( (key == 999 and value == 55) or (key == 1234 and value == 12) )

现在你有有效表达式,你的dataframe也需要修改,因为你无法在arraystruct的列上查询这样的表达式模式

因此,您需要explode函数array元素爆炸到不同的行,然后使用.*表示法选择{{1}的所有元素在不同的列上。

struct

应该为val df1 = df.withColumn("metadata", explode($"metadata")) .select($"metadata.*") 提供

dataframe

最后使用生成的+-----+-----+ |key |value| +-----+-----+ |84896|54 | |1234 |12 | +-----+-----+ 上的有效表达式

dataframe

我希望答案很有帮助