多樣性數據源是報表開發的常見問題,但用JasperReport等報表工具本身難以處理,比如展現兩個MongoDB collection連接的結果。雖然JasperReport有virtual data source或table join,但這些功能只在商業版或高端版本出現,在免費版中實現的難度很大。而且這些功能只支持兩個數據源的連接,要實現多連接則麻煩得多。另外,這些功能只是圖形化界面,無法對連接後的數據進行類似SQL的結構化計算。
集算器具有結構化強計算引擎,支持多樣性數據源,集成簡單,可以協助報表工具方便地實現此類需求。下面通過一個例子來說明MongoDB join的實現過程。
Sales和emp是MongoDB中的兩個collection,sales中的字段SellerId邏輯上相當於外鍵,指向emp的EId字段,現在需要按時間段查詢出sales中的訂單,並和emp進行左連接,最後在報表中展現。部分源數據如下:
Collection sales
<喎?http://www.Bkjia.com/kf/ware/vc/" target="_blank" class="keylink">vcD4KPHA+ICAgICAgIENvbGxlY3Rpb25lbXA8L3A+Cgo8aW1nIHNyYz0="http://www.2cto.com/uploadfile/Collfiles/20150624/20150624100459360.jpg" alt="\">
集算器腳本:
A1=MongoDB("mongo://localhost:27017/test?user=root&password=sa")
上述代碼用來創建MongoDB的數據庫連接,可用user和password來指定用戶名和密碼。
集算器也支持用JDBC方式連接MongoDB,用法和普通數據庫一樣,但由於第三方JDBC不僅收費,而且功能上不如官方庫函數,比如無法獲取多層數據,因此集算器直接封裝原生方法,MongoDB的功能和語法都被保留,比如可以在此基礎上使用find函數,
A2=A1.find("sales","{"$and':[{'OrderDate':{'$gte':'"+string(begin)+"'}},{'OrderDate':{'$lte':'"+string(end)+"'}}]}","{_id:0}").fetch()
上述代碼從MongoDB的salescollection中查詢出某時間段的記錄。函數find的第一個參數是collection名,第二個參數是查詢條件,遵循MongoDB規范,第三個參數限定返回的字段。注意查詢條件中的begin和end是來自報表的外部參數,分別表示OrderDate的起始時間和終止時間。
函數find返回的是游標,並不會把數據直接讀入內存,因此支持大數據量。可以用skip、sort、conj等函數繼續操作游標,直到遇到函數fetch、groups,或語句for時才會真正取數。本例直接用函數fetch()將數據讀入內存,假如時間段是2009-01-01到2009-12-31,則A2的計算結果如下:
A3=A1.find("emp",,"{_id:0}").fetch()
上述代碼從emp collection取數,無條件,除了_id之外取出所有字段,結果如下:
A4=A1.close()
上述代碼用來關閉A1中的數據庫連接。
A5=join@1(A2:sales,SellerId;A3:emp,EId)
上述代碼將A2和A3進行左連接,連接字段是A2的SellerId和A3 的Eld,直觀起見,連接後的兩部分數據分別命名為sales和emp。函數join執行連接計算,選項@1表示左連接,計算結果如下圖左側: