MongoDB 可以用 SQL 查询吗?
关系数据库数据模型简单,都是行列分明的单层二维表,用 SQL 就相对简单,而 MongoDB 里是多层嵌套的结构,属性字段任意出现,光是描述清楚选取哪一层的哪些字段信息,都是件不容易的事。有些第三方工具也能支持在 MongoDB 上使用 SQL,但实际上是能力非常有限,无法处理 JSON 存储中涉及的嵌套结构,也只是 SQL 全部功能的一个子集。其实如果使用Open-esProc,先通过 MongoDB 简单查询,再结合 SPL 语法(类 SQL 的计算),不仅能完成 SQL 的全部功能,而且特别擅长处理多层数据。
比如, 对内嵌文档中的数据求和, 要统计每条记录的 income,output 的数量和, 数据如下。
_id | income | output |
1 | {"cpu":1000, "mem":500, "mouse":"100"} | {"cpu":1000, "mem":600 ,"mouse":"120"} |
2 | {"cpu":2000, "mem":1000, "mouse":"50","mainboard":500 } |
{"cpu":1500, "mem":300 } |
期待统计结果
_id | income | output |
1 | 1600 | 1720 |
2 | 3550 | 1800 |
A | B | |
1 | =mongo_open("mongodb://127.0.0.1:27017/raqdb") | |
2 | =mongo_shell(A1,"computer.find()").fetch() | |
3 | =A2.new(_id:ID,income.array().sum():INCOME,output.array().sum():OUTPUT) | |
4 | >A1.close() |
而如果非要用 SQL 处理,可能就要写成 SELECT _id:ID,income.array().sum():INCOME,output.array().sum():OUTPUT FROM computer,显然不是传统 SQL 能支持的。
SPL 不仅能完全支持类似 SQL 的功能,还可以简化 MongoDB 的查询脚本。比如,统计各段内的记录数量。下面按销售量分段,统计各段内的数据量,数据如下:
_id | NAME | STATE | SALES |
1 | Ashley | New York | 11000 |
2 | Rachel | Montana | 9000 |
3 | Emily | New York | 8800 |
4 | Matthew | Texas | 8000 |
5 | Alexis | Illinois | 14000 |
分段方法:0-3000;3000-5000;5000-7500;7500-10000;10000 以上。
期望结果:
Segment | number |
3 | 3 |
4 | 2 |
按条件分段分组,mongoDB 没有提供对应的处理方法,实现起来比较繁琐,如果用 SPL 则非常简单:
A | B | |
1 | [3000,5000,7500,10000,15000] | |
2 | =mongo_open("mongodb://127.0.0.1:27017/raqdb") | |
3 | =mongo_shell(A2,"sales.find()").fetch() | |
4 | =A3.groups(A1.pseg(int(~.SALES)):Segment;count(1): number) | |
5 | >A2.close() |
其实,MongoDB 里很多复杂查询计算,都能用简洁的 SPL 脚本实现,想了解更多计算示例,参见 玩转 Mongo 计算
SPL 脚本对 MongoDB 数据进行计算后,其结果还可以被 java 应用程序很容易地使用。SPL 有专门的 JDBC 驱动程序,通过 JDBC 调用 SPL 脚本,返回结果集,详情参考 用 Java 如何对 MongoDB 执行类似 SQL 的查询?