MongoDB 怎么实现 IN 子查询
MongoDB作为 NoSql 的数据库,数据存储就比较随意了,每条记录可拥有不同字段集,但对结构化计算能力方面较弱。比如 MongoDB 不支持子查询,碰到这些复杂的运算就只能先将数据读出后再计算。
比如有两个集合 ORDERS、DEALER,查找来自New York的订单信息,要求 ORDERS 订单中的 SELLERID 必须是 DEALER 集合中 STATE='New York'的销售商 PID。如果写成 sql 就是:
Select * from ORDERS where SELLERID in (select PID from DEALER where STATE='New York')
ORDERS | ORDERID | CLIENT | SELLERID | AMOUNT | ORDERDATE |
30 | YZ | 19 | 14600.0 | 2019-11-29 | |
31 | QHHW | 6 | 13800.0 | 2019-12-01 | |
32 | SAVEA | 9 | 5684.0 | 2019-12-08 | |
… | … |
DEALER | PID | NAME | SURNAME | GENDER | STATE | BIRTHDAY |
3 | Rebecca | Moore | F | New York | 1974-11-20 | |
4 | Ashley | Wilson | F | California | 1980-07-19 | |
5 | Rachel | Johnson | F | New Mexico | 1970-12-17 | |
… | … |
使用集算器, 可进行 IN 子查询操作,实现比较容易。
集算器安装包可去润乾网站下载,运行时需要一个授权,免费版本就够用。
我们将上述事例实现步骤:
1. 在集算器中编写脚本 dealer.dfx:
A | B | |
1 | =mongo_open("mongodb://127.0.0.1:27017/raqdb") | / 连接 MongDB 数据库 |
2 | =mongo_shell(A1,"ORDERS.find(,{_id:0})") | / 获取集合 ORDERS 数据 |
3 | =mongo_shell(A1,"DEALER.find({STATE:'New York '},{PID:1, _id:0})").fetch() | / 查询集合 DEALER 中的 PID 数据 |
4 | =A3.(PID).sort() | / 取出 PID 并排序 |
5 | =A2.select(A4.pos@b(SELLERID)).fetch() | / 查询 SELLERID 存在 PID 中的记录 |
6 | >A1.close() | / 关闭连接 |
A5 | ORDERID | CLIENT | SELLERID | AMOUNT | ORDERDATE |
31.0 | QHHW | 6.0 | 13800.0 | 2019-12-01 | |
32.0 | SAVEA | 9.0 | 5684.0 | 2019-12-08 | |
… | … |
A4:A2.join() 中前面 sid, mid 两个为 A2 字段,与 A3 中的两个对应。
集算器提供了 JDBC 接口,脚本 dealer.dfx 很容易集成到 Java 中:
public static void doWork() {
java.sql.Statement st;
try{
Class.forName("com.esproc.jdbc.InternalDriver");
con = DriverManager.getConnection("jdbc:esproc:local://");
// 调用脚本 dealer.dfx
st=con.createStatement();
ResultSet rst = st.executeQuery("call dealer");
System.out.println(rst);
} catch(Exception e){
System.out.println(e);
} finally{
// 关闭连接
if (con!= null) {
try {
con.close();
} catch(Exception e) {
System.out.println(e);
}
}
}
}
对 IN、EXISTS、ANY 和 ALL 的查询,都可以借助集算器来实现。
集算器与 JAVA 集成的进一步信息可参考:《Java 如何调用 SPL 脚本》。
英文版