MongoDB 如何通过数组字段进行关联查找

本文介绍如何在MongoDB中通过数组字段进行关联查找,特别是当数组字段如users.WorkId与workouts._id相关联时。文中提到了使用$lookup和unwind的繁琐方法,然后推荐使用集算器进行更简单的实现。集算器允许通过脚本直接筛选workouts中_id存在于users.WorkId的记录,并将name追加到结果集中。同时,提供了集算器与Java集成的示例代码,帮助开发者将SPL脚本集成到Java应用中。

从关联表记录数组中查找符合条件的数据, 用给定的字段组合成新表。
如有两集合 users, workouts,数组字段 users.WorkId 与 workouts._id 有关联。

users_idNameWorkId
1000xxx[2,4,6]
1002yyy[1,3,5]
workouts_idDateBook
11/1/2001Othello
22/2/2001A   Midsummer Night's Dream
33/3/2001The Old   Man and the Sea
44/4/2001GULLIVER'S   TRAVELS
55/5/2001Pickwick   Papers
66/6/2001The Red   and the Black
77/7/2001Running

  期望查询结果:

Name_idDateBook
xxx22/2/2001A   Midsummer Night's Dream
xxx44/4/2001GULLIVER’S   TRAVELS
xxx66/6/2001The Red   and the Black
yyy11/1/2001Othello
yyy33/3/2001The Old   Man and the Sea
yyy55/5/2001Pickwick   Papers

用 MongoDB 脚本实现思路,可用 $lookup 函数将 users,workouts 两个集合关联查询,用 unwind 拆解 users. workouts成记录,并将它们提升到预层 (与 NAME 同层),再显示需要的列,实现过程比较烦琐。

使用集算器, 只要将 workouts._id 存在 users.WorkId 中的记录的 name 追加到 workouts 集合即可,实现比较容易。

集算器安装包可去润乾网站下载,运行时需要一个授权,免费版本就够用。
我们将上述描述事例实现步骤:

1.    在集算器中编写脚本workout.dfx:

AB
1=mongo_open("mongodb://127.0.0.1:27017/raqdb")/ 连接 MongDB 数据库
2=mongo_shell(A1,"users.find()").fetch()/ 获取集合 users 数据
3=mongo_shell(A1,"workouts.find()").fetch()/ 获取集合 workouts 数据
4=A2.conj(A3.select(A2.WorkId.pos(_id)).derive(A2.name:Name))/ 查询序表 A3 的 _id 值存在于序表 A2 中 WorkId 数组的记录, 并追加 name 字段,返回合并的序表。
5>mongo_close(A1)/ 关闭连接

2.      执行脚本返回结果:

_idDateBookName
22/2/2001A   Midsummer Night's Dreamxxx
44/4/2001GULLIVER’S   TRAVELSxxx
66/6/2001The Red   and the Blackxxx
11/1/2001Othelloyyy
33/3/2001The Old   Man and the Seayyy
55/5/2001Pickwick   Papersyyy

A4:A3.select() 就是 workouts 查询 _id 存在 users.WorkId 中的记录,把结果集的 name 追加到 workouts。

集算器提供了 JDBC 接口,脚本 workout.dfx 很容易集成到 Java 中:
public static void doWorkout() {
    Connection con = null;
    java.sql.Statement st;
   
    try{
        Class.forName("com.esproc.jdbc.InternalDriver");
        con = DriverManager.getConnection("jdbc:esproc:local://"); 
st=con.createStatement(); 
// 调用脚本 workout.dfx
ResultSet rst = st.executeQuery("call workout");
        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);
            }
        }  
    }
}

集算器与 JAVA 集成的进一步信息可参考:《Java 如何调用 SPL 脚本》。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值