用中文進行大資料查詢
概述
如何降低人們使用資料的門檻,這是一個有意思,而又不那麼容易回答的問題。大家習慣從 WYSIWYG(What You See Is What You Get)的角度去出發,由此誕生了一些列的分析工具,例如Tableau,Pentaho
但是在拖拽語義和查詢語義的表達和翻譯上,總會產生歧義,這樣的結果勢必就造成了,如果我們更傾向於降低門檻,那我們就必須捨棄一部分功能,如果我們選擇了功能,那麼我們就需要讓渡一些易用性了。
對於熟悉使用SQL的人來說,可能沒有什麼比直接使用SQL更簡單的方式來獲取資料了。 但是非技術人員,看到SQL可能就像看天書了。
我實現了一個簡版的中文查詢的DSL,下面我們通過一個例項,來講解一下這個DSL,以及他是如何實現的!
例項
從技術上講,這也是一門DSL,只是用中文來做了關鍵字。下面我們來看一個例項:
查詢 { 本次 使用 資料庫{ //username="1" //password="1" //url="jdbc:mysql://localhost:3306/1" //driver="com.mysql.jdbc.Driver" } 本次表 組("gtp_user","gtp_user_role") 本次欄位 組("gtp_user.name","gtp_user_role.role_id") 本次條件 "gtp_user.name = 'admin'" 本次聚合 組("gtp_user.name","gtp_user_role.role_id") 本次排序 組("gtp_user_role.role_id") 本次擷取 (1 到 11) } 畫 線圖
下面我們來逐步解析這個案例,首先構建一個 查詢
,這其實是在構建一個查詢物件,在這個查詢物件的作用域內, 本次
代表當前的查詢。
說明
首先需要指定使用的資料庫, 本次 使用 資料庫 {}
裡面可以使用你自己的資料來源,去掉註釋,修改成你自己的資料來源即可。目前只設置了基礎屬性。
現在支援的查詢謂詞: 表
、 欄位
、 條件
、 聚合
、 排序
、 擷取
支援的動作謂詞: 畫
( 線圖
、 餅圖
、 表
)、 轉
( CSV
、 HTML
、 JSON
)
其他: 組
、 到
表
:用來設定查詢的表,輸入 表名,必填屬性,需要使用雙引號括起來。可與組聯用。
欄位
:用來設定查詢欄位,輸入 表名.欄位名 ,必填屬性,需要使用雙引號括起來。可與組聯用。
條件
:用來設定查詢條件表示式,暫時只能將所有條件一起輸入, 可選屬性,需要使用雙引號括起來。
聚合
:用來設定查詢的聚合欄位,輸入 表名.欄位名, 可選屬性,需要使用雙引號括起來。可與組聯用。
排序
:用來設定查詢的排序欄位,輸入 表名.欄位名, 可選屬性,需要使用雙引號括起來。可與組聯用。
擷取
:用來設定查詢的結果集數量,輸入 數字,例如:到 10,就是取前10條,或是輸入 (數字 到 數字) , 例如: (5 到 10),獲取從第五條開始的10條資料。
畫
:用來將結果輸出,目前支援,線圖、餅圖和表,不 需要使用雙引號括起來
轉
:用來講結果格式化輸出,目前支援格式CSV、HTML、JSON, 需要使用雙引號括起來
實現
這個DSL整體的執行流程,如下圖:
首先DSL,會提交給解析程式,解析成攜帶資料的節點,然後根據節點進行邏輯計劃及優化程式,然後交給物理引擎取執行。
目前解析器,使用了kotlin作為語法解析器,JOOQ充當物理計劃執行器。
其實groovy的AST更適合做DSL,但是社群的活躍度明顯不如kotlin。而且kotlin的語法特性也相當不錯,構建DSL也是信手拈來,整個DEMO到現在寫了10來個小時,已經可以初步的玩一玩了,有興趣的同學可以掃描二維碼: