簡體   English   中英

如何在結構化流中從具有不同模式(具有一些可選對象)的 kafka 主題中讀取數據

[英]How to Read data from kafka topic with different schema (has some optional objects) in structured streaming

我有來自 kafka 主題的數據,其中有一個可選的 object,並且由於它是可選的,因此在使用定義的模式讀取時我會丟失這些記錄

前任:

架構我有:

val schema =new StructType()
      .add("obj_1", new ArrayType(
        new StructType(
          Array(
            StructField("field1",StringType),
            StructField("field2",StringType),
            StructField("obj_2",new ArrayType(
              new StructType(
                Array(
                  StructField("field3",StringType),
                  StructField("field4",LongType),
                  StructField("obj_3",new ArrayType(
                    new StructType(
                      Array(
                        StructField("field5",StringType),
                        StructField("field6",StringType),
                      )
                    ),containsNull = true
                  )
                  )
                )
              ),containsNull = true
            )),
            StructField("field7",StringType),
            StructField("field8",StringType))), containsNull = true))
   

在向該主題發布數據時,我們有時不會根據某些條件發送 obj_3。

因此,當閱讀主題並將其映射到上述模式時,我們會丟失不包含那些 obj_3 並且只包含存在 obj_3 的數據的數據。

如何讀取有時沒有 obj_3 的數據。

示例代碼:

 val df = spark.readStream
        .format("kafka")
        .option("kafka.bootstrap.servers","bootstrap.servers")
        .option("subscribe", "topic.name")
        .option("startingOffsets", "offset.reset)
        .option("failOnDataLoss","true")
        .load()

      val cast = df.selectExpr( "CAST(value AS STRING)")
        .as[( String)]

val resultedDf = cast.select(from_json(col("value"), schema).as("newDF"))

 val finalDf = resultedDf.select(col("newDF.*"))

你也可以

  • 在 Kafka 消息的Key中使用一個標志(例如,在 JSON 結構中稱為“obj3flag”),告訴您的結構化流作業是否 obj_3 存在於 Kafka中,然后選擇一個或另一個模式來解析 json細繩。 就像是:
import org.apache.spark.sql.funtions._
val schemaWithObj3 = ...
val schemaWithOutObj3 = ...

val cast = df.selectExpr("CAST(key AS STRING)", "CAST(value AS STRING)")
        .as[(String, String)]

val resultedDf = cast
  .withColumn("obj_3_flag", get_json_object(col("key"), "$.obj3flag"))
  .withColumn("data", when(col("obj3_flag") === lit(1), from_json(col("value"), schemaWithObj3).otherwise(from_json(col("value"), schemaWithOutObj3))) 
  .select(col("data.*"))
  • 在 Kafka 值(轉換為字符串)中對“obj_3”進行字符串搜索,如果找到該字符串,則應用一個或另一個模式來解析 json。 該代碼看起來與另一個選項的代碼非常相似。

請注意,我已經在手機上編寫了代碼,因此您可能會發現一些語法問題。 但是,希望這個想法能得到傳達。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM