協助 mongodb 計算之數位比較

摘要】


編寫數位比較這類集合式運算,用 Mongodb 腳本或 Java 等高級語言來實現都比較麻煩,但可以利用集算器 SPL 語言來進行輔助實現。若想了解更多,請前往乾學院:協助 mongodb 計算之數位比較!

Mongodb腳本解決複雜問題的計算能力有限,直接使用時較為吃力。很多情況下需要將數據讀出後在主程序中進一步完成運算,而在Java等高級語言中編寫這類集合式運算也比較麻煩。這時可以用集算器SPL語言來輔助實現,下面用例子說明。

Mongodb中有一個test集合如下:

> db.test.find({},{"_id":0})
{"value" : NumberLong(112937552) }
{"value" : NumberLong(715634640) }
{"value" : NumberLong(487229712) }
{"value" : NumberLong(79198330) }
{"value" : NumberLong(440998943) }
{"value" : NumberLong(93148782) }
{"value" : NumberLong(553008873) }
{"value" : NumberLong(336369168) }
{"value" : NumberLong(369669461) }

具體的需求:test集合包含多個value,每個value是一個數字串。每個數字串都要和另外所有的數字串比較,找出每個數字串的最大相同數和最大不同數。如果第1行和第n行都含有數字1,就算相同數有1個,否則第1行有1但第n行沒有,就算不同數有1個。

使用集算器 SPL 的代碼如下:


協助 mongodb 計算之數位比較


A1:連接mongodb,ip和端口號是localhost:27017,數據庫是test,用戶名和密碼都是test。

A2:使用find函數從mongodb中取數,形成遊標。集合是test,過濾條件是空,鍵_id不取出。SPL的遊標支持分批讀取和處理數據,可以避免數據量過大,以防內存溢出。因為數據量不大,所以這裡可以直接 fetch 出遊標的所有記錄。

A3: 在A2的基礎上增加兩列same、diff,用來存放最大相同數和最大不同數。同時把value轉成字符串。

A4:針對A3集合循環,循環體是B4到D10。

B4:取當前循環的value。

C4:利用函數將value分拆成單個字符組成的序列,去掉重複的值。

B5:對A3再進行一次內層循環。循環體是C6到D10。

C5:如果內層循環的循環位置和外層當前位置的相等,即為同一個value時,就跳過本次內層循環,繼續進行下一次內層循環。

C6:取得內層循環的value。

C7:定義兩個變量same和diff,分別存放本次比較的相同數和不同數,初始值為0。

C8: 利用循環函數,在內層循環的value中逐個查找外層循環的value分拆的序列數值。如果能找到,則same自加1,否則diff自加1。

C9、C10:將same和diff和A4中的same和diff比較,將較大的重新賦值給A4中的same和diff。

運行結果如下:

協助 mongodb 計算之數位比較

簡言之,SPL 先得到數據記錄後,把每行數字串拆分成單個無重複字符組成的序列,通過內外層循環比較,找出每行數字串的最大相同數和最大不同數。SPL語言在編寫這類集合式運算方面,具有得天獨厚的優勢。

需要說明的是:集算器SPL並不包含mongodb的java驅動包。如果要用SPL訪問mongodb,必須提前將mongodb的java驅動包(例如:mongo-java-driver-3.9.1.jar)放到集算器設置的外部庫目錄extLib\\MongoCli下。

除了在集算器中直接計算,上述使用SPL語言協助mongodb計算的腳本也很容易集成到java中,只要增加一行,寫成return A3即可向java輸出resultset形式的結果,具體的代碼參考SPL教程。同樣,用java調用SPL訪問mongodb也必須將mongdb的java驅動包放到java程序的classpath中。


分享到:


相關文章: