协助 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":"男"}
…
直接用MongoDB的sort函数,无法按照拼音排序:
> 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 以中文拼音方式升序排序。
运行的结果如下:
需要说明的是:集算器esProc并不包含mongodb的java驱动包。用esProc来访问mongodb,必须提前将mongodb的java驱动包(例如:mongo-java-driver-2.12.2.jar)放到集算器设置的外部库目录extLib\MongoCli下。
除了在集算器中直接计算,上述使用SPL协助mongodb计算的脚本也很容易集成到java中,只要增加一行,写成return A5即可向java输出resultset形式的结果,具体的代码参考esProc教程。同样,用java调用esProc访问mongodb也必须将mongdb的java驱动包放到java程序的classpath中。
MongoDB的 java 驱动包下载地址是:
https://github.com/MongoDB/mongo-java-driver/releases。
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 | 西班牙文 | 洪都拉斯 |