簡體   English   中英

在spark中解析類似Json的結構

[英]Parsing Json like structure in spark

我有一個數據結構像這樣的文件

{'analytics_category_id': 'Default', 'item_sub_type': '', 'deleted_at': '', 'product_category_id': 'Default', 'unit_price': '0.000', 'id': 'myntramprdii201907174a72fb2475d84103844083d1348acb9e', 'is_valid': True, 'measurement_uom_id': '', 'description': '', 'invoice_type': 'receivable_debit_note', 'linked_core_invoice_item_id': '', 'ref_3': '741423', 'ref_2': '6001220139357318', 'ref_1': '2022-07-04', 'tax_rate': '0.000', 'reference_id': '', 'ref_4': '', 'product_id': 'Default', 'total_amount': '0.000', 'tax_auth_party_id': '', 'item_type': 'Product', 'invoice_item_attributes': '', 'core_invoice_id': 'myntramprdi20190717a1e925911345463393bc4ac1b124dbe5', 'tax_auth_geo_id': '', 'quantity': 1}


{'analytics_category_id': 'Default', 'item_sub_type': '', 'deleted_at': '', 'product_category_id': 'Default', 'unit_price': '511.000', 'id': 'myntramprdii20190717c749a96d2e7144aea7fc5125287717f7', 'is_valid': True, 'measurement_uom_id': '', 'description': '', 'invoice_type': 'receivable_debit_note', 'linked_core_invoice_item_id': '', 'ref_3': '741424', 'ref_2': '6001220152640260', 'ref_1': '2022-07-07', 'tax_rate': '0.000', 'reference_id': '', 'ref_4': '', 'product_id': 'Default', 'total_amount': '511.000', 'tax_auth_party_id': '', 'item_type': 'Product', 'invoice_item_attributes': '', 'core_invoice_id': 'myntramprdi20190717a1e925911345463393bc4ac1b124dbe5', 'tax_auth_geo_id': '', 'quantity': 1}

我正在嘗試使用 scala 在 Spark 中解析它並從中創建一個數據幀,但由於結構的原因無法這樣做。 我想用"替換'但我的文本也可以有相同的。我需要的是數據的鍵值對。

到目前為止,我已經嘗試過:

read.option("multiline", "true").json("s3://******/*********/prod_flattener/y=2019/m=07/d=17/type=flattened_core_invoices_items/invoice_items_2019_07_17_23_53_19.txt") 

我確實獲得了一些成功,將其作為多行文本閱讀:

read.option("multiline", "true").textFile("s3://********/*********/prod_flattener/y=2019/m=07/d=17/type=flattened_core_invoices_items/invoice_items_2019_07_17_23_53_19.txt")

|               value|
+--------------------+
|{'analytics_categ...|
|{'analytics_categ...|
+--------------------+

我現在如何將鍵讀取為列?

您的問題與條目中用作布爾值的True值相關聯:這在 JSON 中無效,它需要truefalse作為布爾值

如果您的數據集不是很大,最簡單的方法是作為文本加載,修復此問題,寫入固定數據然后重新打開為 json。

import spark.implicits._
import org.apache.spark.sql.types._

val initial = spark.read.text("s3://******/*********/prod_flattener/y=2019/m=07/d=17/type=flattened_core_invoices_items/invoice_items_2019_07_17_23_53_19.txt") 

val fixed = initial
    .select(regexp_replace('value,"\\bTrue\\b","true") as "value")
    .select(regexp_replace('value,"\\bFalse\\b","false") as "value")

fixed.write.mode("overwrite").text("/tmp/fixed_items")

val json_df = spark.read.json("/tmp/fixed_items")
json_df: org.apache.spark.sql.DataFrame = [analytics_category_id: string, core_invoice_id: string ... 23 more fields]

如果您不想臨時數據集,您可以直接使用from_json來解析固定文本值,但您需要事先在 spark 中手動定義架構並在解析后進行一些列重命名:

val jsonSchema = StructType.fromDDL("`analytics_category_id` STRING,`core_invoice_id` STRING,`deleted_at` STRING,`description` STRING,`id` STRING,`invoice_item_attributes` STRING,`invoice_type` STRING,`is_valid` BOOLEAN,`item_sub_type` STRING,`item_type` STRING,`linked_core_invoice_item_id` STRING,`measurement_uom_id` STRING,`product_category_id` STRING,`product_id` STRING,`quantity` BIGINT,`ref_1` STRING,`ref_2` STRING,`ref_3` STRING,`ref_4` STRING,`reference_id` STRING,`tax_auth_geo_id` STRING,`tax_auth_party_id` STRING,`tax_rate` STRING,`total_amount` STRING,`unit_price` STRING")

val jsonParsingOptions: Map[String,String] = Map()

val json_df = fixed
     .select(from_json('value, jsonSchema, jsonParsingOptions) as "j")
     .select(jsonSchema.map(f => 'j.getItem(f.name).as(f.name)):_*)
json_df: org.apache.spark.sql.DataFrame = [analytics_category_id: string, core_invoice_id: string ... 23 more fields]

jsonParsingOptions ,從您發布的片段來看,您似乎不需要multiline選項,但如果確實需要,則需要將該選項添加到jsonParsingOptions映射中。

暫無
暫無

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

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