我正在尝试从Kafka主题中读取消息。消息采用以下格式(示例格式):
{"schema":{"type":"struct","name":"emp_table","fields":[{"field":"emp_id","type":"string"},{"field":"emp_name","type":"String"},{"field":"city","type":"string"},{"field":"emp_sal","type":"string"},{"field":"manager_name","type":"string"}]},"payload":{"emp_id":"1","emp_name":"abc","city":"NYK","emp_sal":"100000","manager_name":"xyz"}}
另外,请注意主题具有来自不同表的消息,而不仅仅是来自1个表。
我要实现的目标是使用Spark结构化流技术从Kafka Topic阅读以上消息,并创建一个数据列,其列名和值均来自JSON消息本身。
我不想使用案例类或StructType显式定义架构。
我尝试过:
val df = spark.readStream.format("kafka").option("kafka.bootstrap.servers", brokers).option("subscribe", "topic1").option("startingOffsets", "earliest").load()
val y=df.select(get_json_object(($"value"), "$.payload").alias("payload")
当我查看Y(它是一个数据框)时,它是1列,有效载荷下的值为该列中的JSON。
如何获取数据框中的单个列?我没有实现。
(再次重申,由于通过Kafka消息传递的消息来自不同的表,因此我不能对模式部分使用泛型案例类或StructType,因此我希望在运行时从JSON本身创建更多的动态Schema。)
答案 0 :(得分:0)
选项1:将Kafka Connect来源更改为设置value.converter.schemas.enable=false
。这只会给您(开始时未包装的有效载荷),然后您可以跳到下面的帖子。
否则,在使用get_json_object(($"value"), "$.payload").alias("payload")
剥离Connect模式之后,需要创建一个Schema对象,然后使用 y.get_json($"payload", schema)
How to read records in JSON format from Kafka using Structured Streaming?
您所有的字段都是字符串,因此看起来像
val schema: StructType = StructType(Seq(
StructField("emp_id", StringType()),
StructField("emp_name", StringType()),
StructField("city", StringType()),
StructField("emp_sal", StringType()),
StructField("manager_name", StringType())
))