jsontostructs to spark in spark结构化流媒体

时间:2017-10-12 16:25:59

标签: java apache-spark apache-spark-sql apache-spark-2.0 spark-structured-streaming

我正在使用Spark 2.2,我正在尝试从Kafka读取JSON消息,将它们转换为DataFrame并将它们作为Row

spark
    .readStream()
    .format("kafka")
    .option("kafka.bootstrap.servers", "localhost:9092")
    .option("subscribe", "topic")
    .load()
    .select(col("value").cast(StringType).as("col"))
    .writeStream()
    .format("console")
    .start();
用这个我可以实现:

+--------------------+
|                 col|
+--------------------+
|{"myField":"somet...|
+--------------------+

我想要更像这样的东西:

+--------------------+
|             myField|
+--------------------+
|"something"         |
+--------------------+

我尝试使用from_json使用struct函数:

DataTypes.createStructType(
    new StructField[] {
            DataTypes.createStructField("myField", DataTypes.StringType)
    }
)

但我只有:

+--------------------+
|  jsontostructs(col)|
+--------------------+
|[something]         |
+--------------------+

然后我尝试使用explode,但我只有Exception说:

cannot resolve 'explode(`col`)' due to data type mismatch: 
input to function explode should be array or map type, not 
StructType(StructField(...

知道如何使这项工作吗?

1 个答案:

答案 0 :(得分:8)

你几乎就在那里,只选择正确的东西。 from_json会返回与架构匹配的struct列。如果schema(JSON表示)如下所示:

{"type":"struct","fields":[{"name":"myField","type":"string","nullable":false,"metadata":{}}]}

你将获得相当于的嵌套对象:

root
 |-- jsontostructs(col): struct (nullable = true)
 |    |-- myField: string (nullable = false)

您可以使用getField(或getItem)方法选择特定字段

df.select(from_json(col("col"), schema).getField("myField").alias("myField"));

.*选择struct中的所有顶级字段:

df.select(from_json(col("col"), schema).alias("tmp")).select("tmp.*");

虽然对于单个string列,get_json_object应该绰绰有余:

df.select(get_json_object(col("col"), "$.myField"));