协助 MongoDB 计算之本地化排序

**【摘要】**
      Mongodb 本地化排序操作支持还待完善,但结合集算器 SPL 语言来实现就容易多了,不用担心 Mongodb 对集合是否进行过语言设置。若想了解更多,请前往乾学院:协助 MongoDB 计算之本地化排序!

       软件本地化,可让用户根据自己的语言环境、使用习惯来选择不同的语言版本,从而最大限度提高使用体验。随着软件技术的进步,本地化能力得到广泛支持、不断向前发展,也成为软件成熟的重要标志。本文讨论的MongoDB本地化排序之路也是从无到有,一点点积累向前发展的。先前版本只能按照UNICODE编码排序,而不是根据本地语言的编码排序。后来版本增加了对本地化排序的支持,但它的前提是要在创建集合时进行语言设置,否则无效,而且对已经存储了数据的集合也无效。通过集算器SPL语言结合MongoDB进行操作则可以方便实现本地化语言的排序(例如:中文按照拼音排序),实现起来也非常容易。下面就用中文例子进行说明:

       集合person保存了姓名和性别如下:
> db.person.find()
{"_id" : ObjectId("544e4e070f03ad39eb2bf498"), "name" : "宋江","gender":""}
{"_id" : ObjectId("544e4e070f03ad39eb2bf499"), "name" : "李逵","gender":""}
{"_id" : ObjectId("544e4e070f03ad39eb2bf49a"), "name" : "吴用","gender":""}
{"_id" : ObjectId("544e4e070f03ad39eb2bf49b"), "name" : "晁盖","gender":""}
{"_id" : ObjectId("544e4e070f03ad39eb2bf49c"), "name" : "公孙胜","gender":"" }
{"_id" : ObjectId("544e4e070f03ad39eb2bf49d"), "name" : "鲁智深","gender":"" }
{"_id" : ObjectId("544e4e070f03ad39eb2bf49e"), "name" : "武松","gender":""}
{"_id" : ObjectId("544e4e070f03ad39eb2bf49f"), "name" : "阮小二","gender":"" }
{"_id" : ObjectId("544e4e070f03ad39eb2bf4a0"), "name" : "杨志","gender":""}
{"_id" : ObjectId("544e4e070f03ad39eb2bf4a1"), "name" : "孙二娘","gender":"" }
{"_id" : ObjectId("544e4e070f03ad39eb2bf4a2"), "name" : "扈三娘","gender":"" }
{"_id" : ObjectId("544e4e080f03ad39eb2bf4a3"), "name" : "燕青","gender":""}

       直接用MongoDBsort函数,无法按照拼音排序:
> db.person.find({},{"name":1,"gender":1,"_id":0}).sort({"name":1})
{ "name" : "公孙胜","gender":"" }
{ "name" : "吴用","gender":"" }
{ "name" : "孙二娘","gender":"" }
{ "name" : "宋江","gender":"" }
{ "name" : "扈三娘","gender":"" }
{ "name" : "晁盖","gender":"" }
{ "name" : "李逵","gender":"" }
{ "name" : "杨志","gender":"" }
{ "name" : "武松","gender":"" }
{ "name" : "燕青","gender":"" }
{ "name" : "阮小二","gender":"" }
{ "name" : "鲁智深","gender":"" }

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

A
1 =mongo_open("mongodb://localhost:27017/local?user=test&password=test")
2 =mongo_shell(A1,"person.find(,{name:1,gender:1,_id:0})")
3 =A2.fetch()
4 =mongo_close(A1)
5 =A3.sort(name:1;"zh")

A1:连接 MongoDB,连接字格式为 mongo://ip:port/db?arg=value&…。
A2:使用 find 函数从 person 中取数,形成游标,过滤条件是空,指定键是 name 和 gender。SPL 的游标是分批读取和处理数据,可以避免数据量过大,以防内存溢出。
A3:因为数据量不大,所以这里 fetch 出游标的所有记录。
A4:关闭连接。
A5:使用 sort 按照字段 name 以中文拼音方式升序排序。
运行的结果如下:
        

       sort 排序时,可根据需要设置成不同的语言,实现对查询结果的排序。集算器SPL 也支持其他本地化语言,见后面说明。

       需要说明的是:集算器esProc并不包含mongodbjava驱动包。用esProc来访问mongodb,必须提前将mongodbjava驱动包(例如:mongo-java-driver-2.12.2.jar)放到集算器设置的外部库目录extLib\MongoCli下。

       除了在集算器中直接计算,上述使用SPL协助mongodb计算的脚本也很容易集成到java中,只要增加一行,写成return A5即可向java输出resultset形式的结果,具体的代码参考esProc教程。同样,用java调用esProc访问mongodb也必须将mongdbjava驱动包放到java程序的classpath中。

       MongoDB的 java 驱动包下载地址是:
       https://github.com/MongoDB/mongo-java-driver/releases

       集算器 SPL 支持的语言包括:
ja_JP 日文 日本
es_PE 西班牙文 秘鲁
en 英文
ja_JP_JP 日文 日本
es_PA 西班牙文 巴拿马
sr_BA 塞尔维亚文 波斯尼亚和黑山共和国
mk 马其顿文
es_GT 西班牙文 危地马拉
ar_AE 阿拉伯文 阿拉伯联合酋长国
no_NO 挪威文 挪威
sq_AL 阿尔巴尼亚文 阿尔巴尼亚
bg 保加利亚文
ar_IQ 阿拉伯文 伊拉克
ar_YE 阿拉伯文 也门
hu 匈牙利文
pt_PT 葡萄牙文 葡萄牙
el_CY 希腊文 塞浦路斯
ar_QA 阿拉伯文 卡塔尔
mk_MK 马其顿文 马其顿王国
sv 瑞典文
de_CH 德文 瑞士
en_US 英文 美国
fi_FI 芬兰文 芬兰
is 冰岛文
cs 捷克文
en_MT 英文 马耳他
sl_SI 斯洛文尼亚文 斯洛文尼亚
sk_SK 斯洛伐克文 斯洛伐克
it 意大利文
tr_TR 土耳其文 土耳其
zh 中文
th 泰文
ar_SA 阿拉伯文 沙特阿拉伯
no 挪威文
en_GB 英文 英国
sr_CS 塞尔维亚文 塞尔维亚及黑山
lt 立陶宛文
ro 罗马尼亚文
en_NZ 英文 新西兰
no_NO_NY 挪威文 挪威
lt_LT 立陶宛文 立陶宛
es_NI 西班牙文 尼加拉瓜
nl 荷兰文
ga_IE 爱尔兰文 爱尔兰
fr_BE 法文 比利时
es_ES 西班牙文 西班牙
ar_LB 阿拉伯文 黎巴嫩
ko 朝鲜文
fr_CA 法文 加拿大
et_EE 爱沙尼亚文 爱沙尼亚
ar_KW 阿拉伯文 科威特
sr_RS 塞尔维亚文 塞尔维亚
es_US 西班牙文 美国
es_MX 西班牙文 墨西哥
ar_SD 阿拉伯文 苏丹
in_ID 印度尼西亚文 印度尼西亚
ru 俄文
lv 拉托维亚文(列托)
es_UY 西班牙文 乌拉圭
lv_LV 拉托维亚文(列托) 拉脱维亚
iw 希伯来文
pt_BR 葡萄牙文 巴西
ar_SY 阿拉伯文 叙利亚
hr 克罗地亚文
et 爱沙尼亚文
es_DO 西班牙文 多米尼加共和国
fr_CH 法文 瑞士
hi_IN 印地文 印度
es_VE 西班牙文 委内瑞拉
ar_BH 阿拉伯文 巴林
en_PH 英文 菲律宾
ar_TN 阿拉伯文 突尼斯
fi 芬兰文
de_AT 德文 奥地利
es 西班牙文
nl_NL 荷兰文 荷兰
es_EC 西班牙文 厄瓜多尔
zh_TW 中文 台湾地区
ar_JO 阿拉伯文 约旦
be 白俄罗斯文
is_IS 冰岛文 冰岛
es_CO 西班牙文 哥伦比亚
es_CR 西班牙文 哥斯达黎加
es_CL 西班牙文 智利
ar_EG 阿拉伯文 埃及
en_ZA 英文 南非
th_TH 泰文 泰国
el_GR 希腊文 希腊
it_IT 意大利文 意大利
ca 加泰罗尼亚文
hu_HU 匈牙利文 匈牙利
fr 法文
en_IE 英文 爱尔兰
uk_UA 乌克兰文 乌克兰
pl_PL 波兰文 波兰
fr_LU 法文 卢森堡
nl_BE 荷兰文 比利时
en_IN 英文 印度
ca_ES 加泰罗尼亚文 西班牙
ar_MA 阿拉伯文 摩洛哥
es_BO 西班牙文 玻利维亚
en_AU 英文 澳大利亚
sr 塞尔维亚文
zh_SG 中文 新加坡
pt 葡萄牙文
uk 乌克兰文
es_SV 西班牙文 萨尔瓦多
ru_RU 俄文 俄罗斯
ko_KR 朝鲜文 韩国
vi 越南文
ar_DZ 阿拉伯文 阿尔及利亚
vi_VN 越南文 越南
sr_ME 塞尔维亚文 黑山
sq 阿尔巴尼亚文
ar_LY 阿拉伯文 利比亚
ar 阿拉伯文
zh_CN 中文 中国
be_BY 白俄罗斯文 白俄罗斯
zh_HK 中文 香港
ja 日文
iw_IL 希伯来文 以色列
bg_BG 保加利亚文 保加利亚
in 印度尼西亚文
mt_MT 马耳他文 马耳他
es_PY 西班牙文 巴拉圭
sl 斯洛文尼亚文
fr_FR 法文 法国
cs_CZ 捷克文 捷克共和国
it_CH 意大利文 瑞士
ro_RO 罗马尼亚文 罗马尼亚
es_PR 西班牙文 波多黎哥
en_CA 英文 加拿大
de_DE 德文 德国
ga 爱尔兰文
de_LU 德文 卢森堡
de 德文
es_AR 西班牙文 阿根廷
sk 斯洛伐克文
ms_MY 马来文 马来西亚
hr_HR 克罗地亚文 克罗地亚
en_SG 英文 新加坡
da 丹麦文
mt 马耳他文
pl 波兰文
ar_OM 阿拉伯文 阿曼
tr 土耳其文
th_TH_TH 泰文 泰国
el 希腊文
ms 马来文
sv_SE 瑞典文 瑞典
da_DK 丹麦文 丹麦
es_HN 西班牙文 洪都拉斯