我们正在使用流媒体来消费 EventHub 中的数据。 传入流包含各种类型(大约400种不同类型)的 JSON 记录
每个记录将使用 ProductId 属性进行分类。
示例(记录的传入流):
record1 - { productId: 101, colA: "some-val", colB: "some-val" }
record2 - { productId: 104, colC: "some-val", colD: "some-val" }
record3 - { productId: 202, colA: "some-val", colD: "some-val", colF: "some-val" }
record3 - { productId: 342, colH: "some-val", colJ: "some-val", colK: "some-val" }
每条记录中的属性数各不相同,但是具有相似的 productId 的记录将具有完全相同的属性数。
ProductId的范围为(1-400),记录中的属性数最多为50。
我想阅读上面的JSON记录流并写到不同的镶木地板/三角洲位置,例如
Location(Delta/Parquet) Records
-----------------------------------------------------------------
/mnt/product-101 Contains all records with productId - 101
/mnt/product-104 Contains all records with productId - 104
/mnt/product-202 Contains all records with productId - 202
/mnt/product-342 Contains all records with productId - 342
1)如何从包含不同记录类型的流中创建DataFrame / Dataset?
2)是否可以使用单个火花流并写入不同的增量/拼花位置?
答案 0 :(得分:0)
请注意,使用此方法应该可以,但是会生成很多稀疏数据。
首先创建一个结合了所有列的StructType。
val schema = new StructType().add("productId", LongType)
.add("colA", StringType).add("colB", StringType)
.add("colC", StringType)....
然后使用此架构和from_json函数创建流。
val df1 = df.select(from_json('value, schema).alias("tmp"))
.select("tmp.*")
最后使用partitionBy写入分区的实木复合地板文件。
val query1 = df1
.writeStream
.format("parquet")
.option("path", "/mnt/product/")
.option("checkpointLocation","/tmp/checkpoint")
.partitionBy("productId").start()
这将生成包含所有列的行。最初不在json输入中的列将被标记为null。 Parquet支持写入空值。但是最好先过滤一下。