1. 程式人生 > >輕鬆應對多層JSON資料計算與入庫

輕鬆應對多層JSON資料計算與入庫

JSON作為一種輕量級的資料交換格式,因其易於讀寫和互動的特點,已逐漸成為主流的資料型別之一。常見的程式語言大多都對 JSON 的讀取與解析提供了介面,但是接下來如何把多層 JSON 資料經過篩選、計算並展開成二維資料,就需要開發人員去頭疼了。本文就為大家分享一下如何利用集算器 SPL(結構化處理語言)輕鬆解決 JSON 資料解析入庫的問題。

JSON 資料檔案匯入與解析

根據 JSON 資料檔案的複雜程度,以及不同的需求,我們會分三種情況來討論:

1. 單層的 JSON 資料檔案

我們先從一個簡單的例子入手,看看普通鍵值對映的 JSON 檔案如何讀取。下面是某產品訂單資訊的 JSON 資料檔案:

SPL匯入 JSON 資料檔案只需要簡單的一句指令碼:

= json(file("product.json").read())

不需要寫迴圈函式,也不用解析 JSON 物件,執行一下就可以看到,JSON 資料檔案已經轉換為二維資料序表了:

2. 明細資料相同結構的多層 JSON 資料檔案

接下來,我們看一下多層的 JSON 檔案如何處理。下面是我們要用到的 JSON 資料檔案 orders.json:

可以看到,JSON 資料分為兩層,第一層是 "貨主國家" 和 "貨主地區",第二層是明細資料。現在我們想要從中匯入中國華北和華南地區 2013 年的訂單,讓我們看看如果用 SPL 實現。

這次我們先來定義一下引數:Country、Area 和 Year,分別對應需要匯入的貨主國家、貨主地區和訂購日期的年份。通過定義引數,以後匯入不同國家、地區和年份的時候,就不再需要修改 SPL,只需要提供相應的引數值就行了。這裡需要注意的是,Area 的值是序列,預設值是 [華北, 華南],這樣就可以同時讀取多個地區的資料。如下圖:

我們先看一下 SPL 指令碼:

A

B

1

=json(file("orders.json").read())

=A1.select(貨主國家 ==Country   && Area.contain( 貨主地區))

2

=B1.news(區域訂單;B1. 貨主國家: 貨主國家,B1. 貨主地區: 貨主地區,#1,#2,#3,#4,#5,#6,#7,#8,#9,#10,#11,#12,#13)

=A2.select(year( 訂購日期)==Year)

下面來詳細解釋一下:

第一步:A1 中 =json(file("orders.json").read()),匯入 JSON 檔案生成序表。執行一下,可以看到 JSON 資料按層級被展現出來(在集算器設計器中我們可以通過雙擊“區域訂單”值,來檢視下一層明細資料):

第二步:從圖中可以看到,"貨主國家" 和 "貨主地區" 欄位就在第一層,因此在 B1 中直接呼叫A1.select(貨主國家 ==Country && Area.contain( 貨主地區)) 就可以篩選出中國華北和華南的資料。

第三步:"區域訂單" 是我們想要的明細資料,但是其中不包含 "貨主國家" 和 "貨主地區" 這兩個欄位,因此我們需要把這兩個欄位和區域訂單的明細欄位拼在一起。這麼複雜的需求通過 news 函式就可以一步到位解決。從 A2 格的表示式可以看到引數並不複雜,把 B1. 貨主國家,B1. 貨主地區和 "區域訂單" 的全部欄位拼在一起就可以了。看下執行結果:

第四步:在 B2 中通過=A2.select(year( 訂購日期)==Year)篩選出 "訂購日期" 的年份是 2013 年的資料。

最後讓我們執行一下,可以看到最終得到的二維表完全符合需求:

3. 明細資料不同結構的多層 JSON 資料檔案

因為資料來源的複雜性,JSON 資料檔案的明細資料有可能是不同結構的,我們一起看一下這種 JSON 檔案如何處理。下面是我們要用到的 JSON 檔案 sales.json:

第一層以年和月為維度,第二層以國家為維度,第三層是明細資料。但是明細資料中,由於銷售渠道不同,結構是不完全一致的,比如 "PRODUCTLINE"、"ADDRESSLINE1"、"ADDRESSLINE2" 在明細資料中並不是必須的。現在,我們要從資料中讀取 2017 和 2018 年北美兩個大國美國和加拿大的銷售資料。

為了使用方便,我們還是先定義兩個引數:Year 和 Country:

接下來先看一下 SPL:

A

B

1

=json(file("sales.json").read())

=A1.select(Year.contain(YEAR))

2

=B1.news(MONTHLY_SALES;B1.YEAR:YEAR,B1.MONTH:MONTH,#1,#2)

=A2.select(Country.contain(COUNTRY))

3

=B2.news(NATIONAL_MONTHLY_SALES;B2.YEAR:YEAR,B2.COUNTRY:COUNTRY,ORDERNUMBER,QUANTITYORDERED,PRICEEACH,ORDERLINENUMBER,SALES,ORDERDATE,STATUS,QTR_ID,PRODUCTLINE,MSRP,PRODUCTCODE,CUSTOMERNAME,PHONE,ADDRESSLINE1,ADDRESSLINE2,CITY,STATE,POSTALCODE,TERRITORY,CONTACTLASTNAME,CONTACTFIRSTNAME,DEALSIZE)

下面來詳細解釋一下。

A1格還是把 JSON 檔案匯入為多層序表。

由於年份欄位就在第一層,B1 格中直接呼叫A1.select(Year.contain(YEAR))可以從 A1 中篩選出 2017 和 2018 年份的資料:

接下來 A2 格中我們再次用到了 news 函式,用來把年月欄位和下一層的月銷售明細拼在一起:

B2格中我們通過A2.select(Country.contain(COUNTRY))從中篩選出來美國和加拿大的資料。

然後在 A3 格中,我們再次用到了 news 函式,這次需要把 YEAR,MONTH,COUNTRY 和再下一層的國家月銷售明細拼在一個序表中。由於這個檔案中明細資料可能結構有所不同,我們使用全量的欄位名作為引數來建立序表。欄位的值會根據名稱設定,無此欄位的會預設為空值(例如下圖 "ADDRESSLINE1" 和 "ADDRESSLINE2" 欄位):

執行後可以看到最終結果:

至此,一個多層結構的明細資料結構不完全一致的 JSON 檔案就成功展開成為一個二維表了。

序表入庫

前面介紹了常見的 JSON 資料檔案匯入與解析,接下來是資料入庫的問題。之所以在最後才說入庫,並不是因為複雜,恰恰相反的是,由於前面的例子中最後生成的都是序表,因此更新資料庫就變得非常簡單方便。以前面匯入 JSON 的例子 2 中的訂單表為例:

A

1

=file("orders.json").read()[email protected]().select(貨主國家 ==Country && 貨主地區 ==Area). 區域訂單.select(year( 訂購日期)==Year).derive(Country: 貨主國家,Area: 貨主地區)

2

=connect("demo").update(A1, 訂單; 訂單 ID)

可以看到,更新資料庫只需要一句指令碼!

這裡是比較常見的通過主鍵更新,用序表 A1 通過主鍵訂單 ID 來更新資料庫中的訂單表。SPL 中的 update 函式有很多選項,可以滿足更多的更新資料需求,這裡就不再一一贅述了。

       因此,只要用對了工具,從 JSON 檔案匯入解析到資料入庫,再繁瑣的任務也可以輕鬆應對。除了 JSON 資料檔案,集算器 SPL 還支援各種豐富多樣的資料來源,後續將通過更多的文章繼續分享給大家。