我有一個表在磚叫做owner_final_delta列聯係人保存數據和這個結構:
數組< struct <地址:struct <公寓:字符串,城市:字符串,房子:字符串,poBox:字符串,來源:數組<字符串>,狀態:字符串,街:字符串類型:字符串,郵政編碼:string >,地址:數組< struct <公寓:字符串,城市:字符串,房子:字符串,lastSeen:字符串,poBox:字符串,來源:數組<字符串>,狀態:字符串,街:字符串類型:字符串,郵政編碼:string > >, contactKey:字符串,郵件:數組< struct < emailId:字符串,lastSeen:字符串,來源:數組<字符串> > >,lastModifiedDate:字符串,名字:struct < <字符串> firstname:數組,lastname:數組<字符串>,middleNames:數組<字符串>,禮:數組<字符串>,後綴:數組<字符串> >,電話:數組< struct <擴展:字符串,lastSeen:字符串,線型:字符串、數字:字符串,來源:數組<字符串>,validSince: string > >,關係:字符串,來源:數組<字符串> > >
由此,我想提取emailId。我可以提取聯係人。電子郵件是一個數組,其中包含的emailId本身也可以是一個數組(如果有多個郵件綁定到一個記錄)。下麵是一個例子,一個記錄從contacts.emails回來。類似於業務/公司聯係。所以每個元素在聯係人。電子郵件數組是一個人在業務/公司。此外,每個人可以擁有多個電子郵件(emailId)。
數組
我想實現的是一個列emailId emailId每一行。在上麵的例子中,我想這一個記錄分成9行,每個emailId一個。我試著使用get_json_object但必須做錯了什麼。
選擇get_json_object (cast(聯係人。電子郵件作為字符串),從owner_final_delta emailId .emailId美元)
我試著上麵的查詢以及其他變化像使用STR()或聯係人。郵件[0]美元或聯係人。電子郵件和他們都遇到編譯錯誤或返回null值。我寧願一個解決方案使用SQL(所以它可以很容易地用於表),但任何解決方案的工作。
所以當我讀它,這就是我如何讀它。我改變了臨時視圖表名與其他表所以不會衝突。
Python:
df1 = spark.read.format (csv)。選項(“頭”,“真正的”)。選項(“逃脫”,“\”).option(“多行”,真的).load df1.createOrReplaceTempView (“file_path_where_csv_file_is_located”) (“owner_final_delta1”)顯示(df1)
選擇from_json(聯係人”、“數組”< struct <地址:struct <公寓:字符串,城市:字符串,房子:字符串,poBox:字符串,來源:數組<字符串>,狀態:字符串,街:字符串類型:字符串,郵政編碼:string >,地址:數組< struct <公寓:字符串,城市:字符串,房子:字符串,lastSeen:字符串,poBox:字符串,來源:數組<字符串>,狀態:字符串,街:字符串類型:字符串,郵政編碼:string > >, contactKey:字符串,郵件:數組< struct < emailId:字符串,lastSeen:字符串,來源:數組<字符串> > >,lastModifiedDate:字符串,名字:struct < <字符串> firstname:數組,lastname:數組<字符串>,middleNames:數組<字符串>,禮:數組<字符串>,後綴:數組<字符串> >,電話:數組< struct <擴展:字符串,lastSeen:字符串,線型:字符串、數字:字符串,來源:數組<字符串>,validSince: string > >,關係:字符串,來源:數組<字符串> > > " " ")contacts_parsed,從owner_final_delta1 *
最後一個是SQL。
謝謝你的回應!我試著爆炸功能(這是一個相當危險的名字函數),確保進口pyspark.sql。功能,甚至讓一個新的集群最磚運行時版本的更新,但我仍然得到一個“爆炸沒有定義”錯誤。我甚至嚐試pyspark.sql.functions直接進口。但這種模式無法發現爆炸。
然後我看著“SQL查詢半結構化數據”文檔。我試過一些方法像原始:contacts.emails [*]。emailId但有錯誤圍繞“原始列不存在”,當刪除“生:“我有一個錯誤“無效使用‘*’”。
爆炸,下麵這個代碼給你同樣的錯誤嗎?
從pyspark。sql從pyspark導入函數作為F。sql進口行eDF =火花。createDataFrame([行(= 1,intlist = (1、2、3), mapfield = {“a”:“b”}))) eDF.select (F.explode (eDF.intlist) .alias (“anInt”)),告訴()
對於SQL方法,什麼是表中的列名包含這個JSON結構在每一行嗎?假設它是“接觸”,但你的JSON開始嵌套的“聯係人”則是:
選擇聯係人:contacts.emails [*]。從table_name emailId
同樣的錯誤呢?
我試著你的確切爆炸的例子和它工作。然後我插入我的數據如下所示:
df = sqlContext.table (“owner_final_delta”)
進口pyspark.sql。函數作為F
df.select (F.explode (df.contacts.emails [0] .emailId) .alias(“電子郵件”)),告訴()
這個工作,但注意我用[0](郵件數組的索引0)。我試著使用[*],但我得到了一個無效的語法錯誤。有辦法df.contacts循環。電子郵件和返回一列中的所有.emailIds嗎?
為SQL列名控股JSON結構方法聯係人。所以我試著查詢你所寫的一樣:
選擇聯係人:contacts.emails [*]。從owner_final_delta emailId
這將返回這個錯誤本質上說有一個參數類型不匹配的聯係人不是一個字符串:
在SQL語句錯誤:AnalysisException:不能解決semi_structured_extract_json_multi (spark_catalog.default.owner_final_delta.contacts,“美元.contacts.emails [*] .emailId”)的數據類型不匹配:參數1需要字符串類型,然而,“spark_catalog.default.owner_final_delta.contacts”是數組的< struct <地址:struct <公寓:字符串,城市:字符串,房子:字符串,poBox:字符串,來源:數組<字符串>,狀態:字符串,街:字符串,類型:字符串,郵政編碼:string >,地址:數組< struct <公寓:字符串,城市:字符串,房子:字符串,lastSeen:字符串,poBox:字符串,來源:數組<字符串>,狀態:字符串,街:字符串,類型:字符串,郵政編碼:string > >, contactKey:字符串,郵件:數組< struct < emailId:字符串,lastSeen:字符串,來源:數組<字符串> > >,lastModifiedDate:字符串,名字:struct < firstname:數組<字符串>,lastname:數組<字符串>,middleNames:數組<字符串>,禮:數組<字符串>,後綴:數組<字符串> >,電話:數組< struct <擴展:字符串,lastSeen:字符串,線型:字符串、數字:字符串,來源:數組<字符串>,validSince: string > >,關係:字符串,來源:數組<字符串> > >類型。1號線pos 7;
”項目(semi_structured_extract_json_multi (spark_catalog.default.owner_final_delta.contacts, ' $ .contacts.emails [*] .emailId) emailId # 956)
這應該如何解決呢?