Apache spark 如何将kafka上的spark流式嵌套json转换为平面数据帧?

Apache 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, "

我第一次尝试解析Kafka上的JSON以激发结构化流,需要一些帮助

我正在努力转换传入的JSON并将其转换为平面数据帧以进行进一步处理

我的输入是json

[
    { "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.*")

似乎是重复的问题:[参考此]:()