前言
在mongodb上通过.system.js的特殊系统集合,存储一些MongoDB环境下支持的js函数,供重复使用; 核心是在执行某些查询语句时,返回值中的某些被base64编码的字段无法正常查看,想通过一条语句就能输出base64解码后的字段记录。
注意
本例使用的mongodb版本是4.0.10,不同的版本使用差异较大,MongoDB8.0开始了,system.js 功能并不通用,且不同的版本间使用js函数使用时也有很大不同
- 可能存在性能问题,生产慎用
- 不要在js中写业务逻辑
使用步骤
- 在mongodb中创建一个函数
将JavaScript函数存储在数据库中,插入两个字段:- _id 字段包含函数名称,在每个数据库中都是唯一的
- value 字段保存函数的具体实现
以下示例以增加base64Decode函数为例:
db.system.js.insertOne({ _id: "base64Decode", value: function(encodedString) { var keyStr = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='; // Base64 编码表 var output = ''; var chr1, chr2, chr3, enc1, enc2, enc3, enc4; var i = 0; encodedString = encodedString.replace(/[^A-Za-z0-9\+\/\=]/g, ''); while (i < encodedString.length) { enc1 = keyStr.indexOf(encodedString.charAt(i++)); enc2 = keyStr.indexOf(encodedString.charAt(i++)); enc3 = keyStr.indexOf(encodedString.charAt(i++)); enc4 = keyStr.indexOf(encodedString.charAt(i++)); chr1 = (enc1 << 2) | (enc2 >> 4); chr2 = ((enc2 & 15) << 4) | (enc3 >> 2); chr3 = ((enc3 & 3) << 6) | enc4; output = output + String.fromCharCode(chr1); if (enc3 !== 64) { output = output + String.fromCharCode(chr2); } if (enc4 !== 64) { output = output + String.fromCharCode(chr3); } } return output; }});
- 执行成功后,会提示插入成功,否则会提示各种语法等的错误,做调整重新插入即可
- 将存储成功的函数加载到shell中,这个不会有返回值
db.loadServerScripts()
- 运行已存储的函数
> base64Decode("SGVsbG8gV29ybGQ=") Hello World
- 在查询语句里使用,假设mongoDB的users表中有name和encodedField两个字段,且encodedField字段是base64编码后的字符串,查询结果是encodedField的base64解码后的字符串输出。
> db.users.find({'encodedField': {$ne: null}, 'name': 'tomcat'}, {_id: 0, encodedField: 1}).forEach(function(doc){doc.encodedField = base64Decode(doc.encodedField); print(doc.encodedField);})
# 当需要输出整个document时,可以把print() 改成printjson(doc),就会输出完整的文档信息json形式输出
# ubuntu 环境下也可以通过 shell 命令 echo "SGVsbG8gV29ybGQ=" | base64 --decode 对单一进行解码
参考文档:https://www.mongodb.com/zh-cn/docs/manual/tutorial/store-javascript-function-on-server/