[英]Spark Structured Streaming to read nested Kafka Connect jsonConverter message
[英]Extracting "payload" from Kafka Connect JSONConverter messages with (schema & payload) using Spark Structured Streaming (pyspark)
然而,我想要完成的正是這個問題( 這里)的內容; 就我而言,我使用的是 Python/Pyspark 而不是 Scala。
我正在嘗試提取也包含架構的 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 步 - 為“有效負載”部分定義架構:
payload_schema = StructType([
StructField("emp_id", StringType(), False),
StructField("emp_name", StringType(), True),
StructField("city", StringType(), True),
StructField("emp_sal", StringType(), True),
StructField("manager_name", StringType(), True)])
第 2 步 - 從 Kafka 讀取:
df =spark.readStream.format("kafka")
第 3 步 - 從 Kafka 消息中獲取消息值:
kafka_df = df.selectExpr("CAST(value AS STRING)")
第 4 步 - 僅提取“有效載荷”(我被困在這里):
import pyspark.sql.functions as psf
emp_df = kafka_df\
.select(psf.from_json(psf.col('value'), payload_schema).alias("DF"))\
.select("DF.*")
我被困在這部分,因為我無法弄清楚如何在將它傳遞給 from_json() function 之前從 JSON 字符串中提取有效載荷。
注意:我知道我需要為整個消息定義完整的模式,然后才能在 from_json() 中使用它;但是; 我試圖只獲取“有效負載”json 字符串部分。
您可以使用 SQL function get_json_object
:
import pyspark.sql.functions as psf
kafka_df
.select(psf.get_json_object(kafka_df['value'],"$.payload").alias('payload'))
.select(psf.from_json(psf.col('payload'), payload_schema).alias("DF"))
.select("DF.*")
或者,您需要先為整個消息定義完整模式,然后才能在from_json
中使用它。
這意味着您的模式應該如下所示:
full_schema = StructType([
StructField("schema", StructType([
StructField("type", StringType(), False),
StructField("name", StringType(), False),
StructField("fields", StructType([
StructField("field", StringType(), False),
StructField("type", StringType(), False)
]),
StructField("payload", StructType([
StructField("emp_id", StringType(), False),
StructField("emp_name", StringType(), True),
StructField("city", StringType(), True),
StructField("emp_sal", StringType(), True),
StructField("manager_name", StringType(), True)
])
])
請仔細檢查此模式定義,因為我不完全確定如何在 Python 中的模式中定義數組,但我希望這個想法很清楚。
完成后,您可以通過 select 有效負載字段
import pyspark.sql.functions as psf
emp_df = kafka_df\
.select(psf.from_json(psf.col('value'), full_schema).alias("DF"))\
.select("DF.payload.*")
假設您手頭沒有schema
,您可以這樣做:
import json
df = kafka_df.select(psf.get_json_object(kafka_df.value, "$.payload").alias("payload"))
final_df = df.rdd.map(lambda row: json.loads(row[0])).toDF().show()
出於某種原因,我錯過了 pyspark 有 get_json_object() function。在 Mike 的評論之后,我回到了文檔,我找到了我要找的東西。
答案如下:
kafka_df = df.selectExpr("CAST(value AS STRING)")
payload_df = kafka_df.select(psf.get_json_object(kafka_df.value, "$.payload").alias("payload"))
emp_df = payload_df.select(psf.from_json(psf.col('payload'), schema).alias("DF")).select("DF.*")
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.