如何用 esProc 简化 MongoDB 的查询
MongoDB 自带的查询语法功能比较繁琐,简单的任务也要写很长代码,复杂计算更难实现,比如:
SPL assists MongoDB: Only keep the running total for the last item in the partition
SPL assists MongoDB: Replace substring in array of objects with nested objects
SPL assists MongoDB: Find multiple latest by filter criteria
esProc 提供了 MongoDB 访问接口,内置强大的计算函数,可以简化 MongoDB 的查询。
下面,我们来尝试一下如何将 esProc 集成到应用中。
先下载并安装 esProc,推荐标准版:https://www.raqsoft.com.cn/download/download-jsq
再下载 esProc 外部库,以访问 mongoDB 等外部数据源,同样从上面地址下载。
将外部库的 zip 文件解压在任意目录,比如 d:\esProcSTD\extlib
启动 esProc IDE,打开菜单 "Tools->Options",找到配置项 "External library directory",导航到刚才的目录。
导航到外部库目录后,会显示出数据源列表,在列表中勾选 MongoCli。
重新启动 IDE,新建脚本,编写下面的代码,加载例子 1 的数据:
A | |
1 | =mongo_open("mongodb://127.0.0.1:27017/local") |
2 | =mongo_shell@d(A1, "{'find':'grp_score','projection':{'_id':0}}") |
3 | =mongo_close(A1) |
按 ctrl-F9 执行,可以在 IDE 右边看到 A2 的执行结果,以数据表的形式呈现,这对调试 SPL 代码很方便。
从 MongoDB 简单加载数据后,就可以用 SPL 简化复杂的 MongoDB 的查询了。第 1 个例子的完整代码是:
A | |
1 | =mongo_open("mongodb://127.0.0.1:27017/local") |
2 | =mongo_shell@d(A1, "{'find':'grp_score','projection':{'_id':0}}") |
3 | =mongo_close(A1) |
4 | =A2.select(seq>=arg1 && seq<=arg2) |
5 | =A4.group(grp;(a=~.sort(seq),a.m(-1).x=a.sum(score))) |
6 | =json(A4) |
先通过参数过滤数据,再将汇总值写在本组最后一条记录上。运行后可以看到结果:
把上面脚本保存在某个目录中,比如 D:\data\grp_score.splx,后续 Java 代码会用到。
上面例子 1 是单层数据,下面例子 2 是多层数据:
A | |
1 | =mongo_open("mongodb://127.0.0.1:27017/local") |
2 | =mongo_shell@d(A1, "{'find':'meetings','projection':{'_id':0}}") |
3 | =mongo_close(A1) |
4 | =A2.run(organizer.run(avatar="https://new.com/"+mid(avatar,17)), meetings.run(owner.run(avatar="https://new.com/"+mid(avatar,17)), participants.run(avatar="https://new.com/"+mid(avatar,17)) ) ) |
在 IDE 右边可以逐层展开并观察多层数据,其中 A2 的结构如下:
类似地,把上面脚本保存在目录中,比如 D:\data\meetings.splx。
在 IDE 中调试通过后,下面配置 Java 应用环境。
从目录 "[安装目录]\esProc\lib" 下找到 esProc JDBC 相关的 jar 包:esproc-bin-xxxx.jar、icu4j_60.3.jar。
将这两个 jar 包部署到 Java 开发环境的类路径下。外部库的 jar 包会通过配置文件动态加载,不需要手工部署。
再从目录 "[安装目录]\esProc\config" 下找到 esProc 配置文件 raqsoftConfig.xml,同样部署到 Java 开发环境的类路径下。
比较重要的配置项有两处:mainPath,这是脚本等文件的默认路径;importLibs->lib,这是已经启用的外部库。可以在配置文件里手工修改,也可以通过 IDE 里的配置界面修改。
接下来,就可以编写 Java 代码,通过 esProc JDBC 执行 SPL 了,先试试例子 1:
Class.forName("com.esproc.jdbc.InternalDriver");
Connection con= DriverManager.getConnection("jdbc:esproc:local://");
PreparedStatement st = con.prepareCall("call grp_score(?,?)");
st.setInt(1,1);
st.setInt(2,4);
ResultSet rs = st.executeQuery();
运行后可以看到结果:
可以看到,esProc JDBC 调用 SPL 脚本过程和数据库 JDBC 调用存储过程一样。
例子 2 类似,在 Java 中用文件名调用 SPL 脚本:
Class.forName("com.esproc.jdbc.InternalDriver");
Connection con= DriverManager.getConnection("jdbc:esproc:local://");
PreparedStatement st = con.prepareCall("call meetings()");
ResultSet rs = st.executeQuery();
执行结果像下面这样:
esProc 还支持简单 SQL,方便数据库程序员使用。比如加载例子 1 的数据,再执行 SQL,脚本可以这样写:
A | |
1 | =mongo_open("mongodb://127.0.0.1:27017/local") |
2 | =mongo_shell@d(A1, "{'find':'grp_score','projection':{'_id':0}}") |
3 | =mongo_close(A1) |
4 | $select case grp when 'A' then 'Class 1' when 'B' then 'Class 2' else 'others' end level,sum(score) as subtotal from {A2} where seq>=? and seq<=? group by grp ;arg1,arg2 |
5 | return A4 |
将脚本文件存为 grp_scoreSQL.splx,执行后结果如下:
esProc 官网上还有很多简化 MongoDB 查询的例子,感兴趣的可以看看。
英文版 https://c.esproc.com/article/1743555200077