Apache spark 如何将kafka上的spark流式嵌套json转换为平面数据帧?
我第一次尝试解析Kafka上的JSON以激发结构化流,需要一些帮助 我正在努力转换传入的JSON并将其转换为平面数据帧以进行进一步处理 我的输入是jsonApache spark 如何将kafka上的spark流式嵌套json转换为平面数据帧?,apache-spark,pyspark,apache-kafka,apache-spark-sql,spark-structured-streaming,Apache Spark,Pyspark,Apache Kafka,Apache Spark Sql,Spark Structured Streaming,我第一次尝试解析Kafka上的JSON以激发结构化流,需要一些帮助 我正在努力转换传入的JSON并将其转换为平面数据帧以进行进一步处理 我的输入是json [ { "siteId": "30:47:47:BE:16:8F", "siteData": [ { "dataseries": "trend-255", "values": [ {"ts": 1502715600, "
[
{ "siteId": "30:47:47:BE:16:8F", "siteData":
[
{ "dataseries": "trend-255", "values":
[
{"ts": 1502715600, "value": 35.74 },
{"ts": 1502715660, "value": 35.65 },
{"ts": 1502715720, "value": 35.58 },
{"ts": 1502715780, "value": 35.55 }
]
},
{ "dataseries": "trend-256", "values":
[
{"ts": 1502715840, "value": 18.45 },
{"ts": 1502715900, "value": 18.35 },
{"ts": 1502715960, "value": 18.32 }
]
}
]
},
{ "siteId": "30:47:47:BE:16:FF", "siteData":
[
{ "dataseries": "trend-255", "values":
[
{"ts": 1502715600, "value": 35.74 },
{"ts": 1502715660, "value": 35.65 },
{"ts": 1502715720, "value": 35.58 },
{"ts": 1502715780, "value": 35.55 }
]
},
{ "dataseries": "trend-256", "values":
[
{"ts": 1502715840, "value": 18.45 },
{"ts": 1502715900, "value": 18.35 },
{"ts": 1502715960, "value": 18.32 }
]
}
]
}
]
Spark模式是
data1\u spark\u schema=ArrayType(
结构类型([
StructField(“siteId”,StringType(),False),
StructField(“站点数据”),ArrayType(StructType([
StructField(“数据系列”,StringType(),False),
StructField(“值”),ArrayType(StructType([
StructField(“ts”,IntegerType(),False),
StructField(“值”,StringType(),False)
]),假),假)
]),假),假)
]),错
)
我非常简单的代码是:
从pyspark.sql导入SparkSession
从pyspark.sql.functions导入*
从config.general导入kafka_实例
从config.general导入主题
从schemas.schema导入数据1\u spark\u schema
火花=火花会话\
建筑商先生\
.appName(“结构化的BMS订阅源”)\
.getOrCreate()
流=火花\
.readStream\
.格式(“卡夫卡”)\
.option(“kafka.bootstrap.servers”,kafka_实例)\
.选项(“订阅”,主题)\
.选项(“起始偏移量”、“最新”)\
.选项(“最大投票记录”,100)\
.选项(“failOnDataLoss”,False)\
.load()
stream_records=stream.selectExpr(“转换(键为字符串)”,“转换(值为字符串)为bms_数据1”)\
.select(从_json(“bms_data1”,data1\u spark\u schema)。别名(“bms_data1”))
站点=流记录。选择(分解(“bms\U数据1”)。别名(“站点”))\
.选择(“站点。*”)
sites.printSchema()
stream_debug=sites.writeStream\
.outputMode(“追加”)\
.格式(“控制台”)\
.选项(“numRows”,20)\
.选项(“截断”,False)\
.start()
流_debug.awaitTermination()
当我运行此代码时,我的模式是这样打印的:
root
|-- siteId: string (nullable = false)
|-- siteData: array (nullable = false)
| |-- element: struct (containsNull = false)
| | |-- dataseries: string (nullable = false)
| | |-- values: array (nullable = false)
| | | |-- element: struct (containsNull = false)
| | | | |-- ts: integer (nullable = false)
| | | | |-- value: string (nullable = false)
有没有可能让这个模式在一个平面数据框中获得所有字段,而不是嵌套的JSON。因此,对于每个ts和值,它应该给我一行,带有其父数据系列和站点id。回答我自己的问题。我设法用以下几行将其展平:
sites_flat = stream_records.select(explode("bms_data1").alias("site")) \
.select("site.siteId", explode("site.siteData").alias("siteData")) \
.select("siteId", "siteData.dataseries", explode("siteData.values").alias("values")) \
.select("siteId", "dataseries", "values.*")
似乎是重复的问题:[参考此]:()