跳轉到主要內容
公司博客上

處理嵌套數據使用高階函數在SQL數據磚

分享這篇文章

把這個筆記本磚

嵌套數據類型提供磚客戶和Apache引發用戶的強大處理結構化數據的方法beplay体育app下载地址。特別是,他們允許你把複雜的對象和數組一樣,地圖和內部結構的列。這可以幫助你模型數據在一個更自然的方式。雖然這個功能肯定是有用的,但它會很麻煩操縱數據的內部複雜的對象,因為SQL(火花)沒有原語來處理這些數據。此外,它是耗時的,non-performant和非平凡的。

由於這些原因,我們興奮地提供高階函數的SQL磚運行時的3.0版本,允許用戶高效地創建函數,在SQL操作基於數組的數據。高階函數是一個簡單的擴展SQL操作嵌套數組等數據。例如,變換下麵表達式顯示了如何添加一個數字數組中每個元素:

在這篇文章中,我們將討論以前的方法嵌套SQL數據操作,其次是高階函數語法我們已經介紹了磚。


檢查為什麼Lakehouse的數據是你的下一個數據倉庫的電子書發現磚的內部運作Lakehouse平台。Beplay体育安卓版本

過去的方法

在我們介紹數組操作的新語法之前,讓我們首先討論當前操作這類數據在SQL方法:

  • 內置函數(有限的功能)
  • 解壓縮數組為單個行,應用你的函數,然後重新打包成數組(很多步驟,因此效率低下)
  • udf(不是一般的或有效)

我們將探討這些獨立,這樣你可以理解為什麼數組操作是很困難的。讓我們開始下麵的表的模式(包括看到筆記本容易運行的代碼)。

| - - -關鍵:長(可空=)|——價值觀:數組(可空=)| |——元素:整數(containsNull =真正的)|——nested_values:數組(可空=)| |——元素:數組(containsNull =)| | |——元素:整數(containsNull =真正的)

內置函數

火花SQL確實有一些內置函數用於操作數組。例如,您可以創建一個數組,它的大小,得到特定元素,檢查如果數組包含一個對象,數組進行排序。SQL還支持發電機(火花爆炸,pos_explode內聯),允許您將輸入行數組元素,和collect_list聚合。這個功能可以滿足您的需要對某些任務,但它是複雜的做任何事不平凡的,如計算每個數組元素的一個定製的表達。

解包和重新打包

非平凡的操作的常用的方法是“打開和重新打包”方法。這是一個“火花SQL原生”的方式解決問題,因為你不需要編寫任何自定義代碼;您可以簡單地編寫SQL代碼。打開和重新打包方式是通過以下步驟:

  1. 使用側麵圖爆炸平數組,輸入行與數組中的每個元素相結合;
  2. 應用一個給定的變換,在這個例子中值+ 1爆炸數組中的每個元素;和
  3. 使用collect_listcollect_set創建一個新的數組。

我們可以看到一個這樣的例子在SQL代碼如下:

選擇鍵,,collect_list (價值+1)作為values_plus_onenested_data橫向視圖爆炸()T作為價值集團通過鍵,

雖然這種方法肯定奏效,它有一些問題。首先,你必須絕對確保密鑰用於分組是獨一無二的,否則結果將是不正確的。第二,沒有保證排序數組的火花SQL。指定一個操作,需要一個特定的順序幾乎保證不正確的結果。最後,生成的火花SQL計劃可能會非常昂貴。

用戶定義的函數(udf)

最後,我們可以編寫自定義udf來操作數組的數據。udf必須定義如何遍曆一個數組,我們如何處理單個元素。讓我們看看一些基本例子在Python和Scala。

(code_tabs)

pyspark.sql.types進口IntegerTypepyspark.sql.types進口ArrayTypedefadd_one_to_els(元素):返回[el +1埃爾元素)spark.udf.register (“plusOneIntPython”、add_one_to_els ArrayType (IntegerType ()))
defaddOneToElements(元素:Seq [Int])=元素地圖(= >元素+1)火花udf注冊(“plusOneInt”addOneToElements (_:Seq [Int]):Seq [Int])

[/ code_tabs]

一旦注冊,我們可以使用這些函數來操縱我們的數據在火花SQL。

選擇鍵,,plusOneInt ()作為values_plus_one,plusOneIntPython ()作為values_plus_one_pynested_data

這種方法有一些優勢在過去的版本:例如,它維護元素順序,與包裝和重新打包方法。然而,它有兩個主要缺點。首先,你必須編寫函數在其他語言比SQL和注冊之前運行。第二,數據序列化到Scala和Python可以非常昂貴,減緩udf火花的SQL內置的優化處理

我們的方法:高階函數

從上麵的例子中,觀察到傳統的方式在SQL繁瑣操作嵌套數據。為此,我們建立了一個簡單的解決方案在磚:高階函數的SQL。

運行下麵的例子在這個筆記本上。

我們的解決方案引入了兩個SQL函數編程結構:高階函數和匿名(λ)函數。這些共同允許您定義的函數操作數組在SQL。的高階函數,如變換,和一個數組lambda函數從用戶運行。然後調用這個lambda函數數組中的每個元素。

一個簡單的例子:變換

讓我們說明前麵的概念與我們之前的轉換的例子。在這種情況下,高階函數,變換將遍曆該數組,相關的lambda函數適用於每一個元素,並創建一個新數組。lambda函數,元素+ 1,指定每個元素是如何被操縱的。

選擇鍵,,變換(,價值- - - - - ->價值+1)作為values_plus_onenested_data

清晰的說明,轉換變換(價值觀、價值- >價值+ 1)有兩個組件:

  1. 變換值. .)是高階函數。這需要一個數組和一個匿名函數作為輸入。內部變換將照顧設置一個新數組,每個元素應用匿名函數,分配結果輸出數組。
  2. 值- >值+ 1是一個匿名函數。的功能分為兩個組件分離- >符號:
    一個。參數列表。在這種情況下,我們隻有一個論點:價值。我們也支持多個參數通過創建一個逗號分隔的參數列表包圍括號,例如:(x, y) - > x + y
    b。身體。這是一個表達式,可以使用參數和外部變量計算新值。在這種情況下,我們的值加1的論點。

捕獲變量

我們還可以使用其他比lambda函數中的參數變量;這就是所謂的捕捉。我們可以用變量定義在頂層,或在中間lambda函數定義的變量。例如,下麵的改變增加了關鍵(頂級)變量值數組中的每個元素:

選擇鍵,,變換(,價值- - - - - ->價值+鍵)作為values_plus_keynested_data

嵌套調用

有時數據是深度嵌套。如果你想改變這樣的數據,你可以可以使用嵌套的lambda函數。下麵的例子將整數數組,數組並添加關鍵(頂級)列和中間數組的大小嵌套數組中的每個元素。

選擇鍵,nested_values,變換(nested_values- - - - - ->變換(,價值- - - - - ->價值+關鍵+大小()))作為new_nested_valuesnested_data

支持功能

我們有下麵的高階函數添加到3.0版本的磚運行時

變換(數組 、功能 ):數組

這產生一個數組通過應用函數一個輸入的每個元素數組

注意,函數式編程操作映射。這已經被轉換為了防止混亂的地圖表達(從一個鍵值表達式創建一個地圖)。

下麵的查詢轉換的值數組每個元素通過添加鍵值:

選擇鍵,,變換(,價值- - - - - ->價值+鍵)transformed_valuesnested_data

存在(數組 、功能 ):布爾

返回true,如果謂詞函數適用於任何元素輸入數組

下麵的示例檢查數組包含一個元素的值模10 = 1:

選擇鍵,,存在(,價值- - - - - ->價值%10==1)filtered_valuesnested_data

過濾器(數組 、功能 ):數組

生成一個輸出數組從輸入數組隻有隻有謂詞添加元素函數成立。

下麵的例子過濾器與一個值隻數組元素的值> 50允許:

選擇鍵,,過濾器(,價值- - - - - ->價值>50)filtered_valuesnested_data

總(數組 B函數、功能R):

減少的元素數組成一個單一的值R通過合並元素到一個緩衝區B使用函數並通過應用finish函數在最後一個緩衝區。初始值B是由一個零的表達式。完成的功能是可選的,如果你不指定函數確定函數恒等函數(id - > id)使用。

這是唯一的高階函數,取兩個lambda函數。

下麵的例子總結(骨料)數組的值到一個(總和)值。兩個版本完成函數(summed_values)和一個沒有完成的功能summed_values_simple顯示:

選擇鍵,,減少(,0,(價值,acc)- - - - - ->價值+acc, acc- - - - - ->acc) summed_values,減少(,0,(價值,acc)- - - - - ->價值+acc) summed_values_simplenested_data

你也可以計算更複雜的聚合。下麵的代碼顯示了計算幾何平均數的數組元素。

選擇鍵,,聚合(,(1.0作為產品,0作為N),(緩衝區,價值)- - - - - ->(價值*緩衝區。產品,buffer.N+1),緩衝- - - - - ->權力(buffer.product1.0/buffer.N) geomeannested_data

結論

高階函數將可用磚3.0運行時。如果你有任何嵌套的數據,一定要試一試!

這項工作增加了初始支持使用高階函數嵌套數組數據。額外的功能和支持地圖數據已經在路上了。一定要檢查出磚的博客文檔

免費試著磚

相關的帖子

看到所有公司博客上的帖子
Baidu
map