MongoDB 如何查询嵌套子文档

MongoDB作为 NoSql 的数据库,能通过嵌套子文档,将横向扩展以及性能做到更好,实现一对多的关联关系。应用开发中,对嵌套子文档结构的查询,不熟悉者 MongoDB 也容易陷入误区。如有如下数据

    ……
    {
        "_id": "1001",
        "name": "Storage Beta",
        "items": [
            {  "category":     "food",  "name":     "pear"   },
            {  "category":     "food",  "name":     "peach" },
            {  "category":     "food",  "name":     "grape"},
            
            {   "category":     "tool",  "name":     "knife"},
            {   "category":     "furniture",      "name": "chair"     },
            {   "category":     "furniture",      "name": "bench"}
        ]
}
    ……

查询 category='food' 的子文档,估计不少使用者首先想到用 find() 语句查询:

db.storage.find({'items.category':{ $eq: 'food'}}).pretty();
则返回上面所有的数据,并没有达到过滤数据的目的。MongoDB实现方式确实有点与众不同,需要采用aggregate+$project+$filter+input+cond的组合查询,实现细节就不再赘述。

使用集算器, 可进行 select() 查询操作,实现比较容易。
集算器安装包可去润乾网站下载,运行时需要一个授权,免费版本就够用。

我们将上述事例实现步骤:
1.    在集算器中编写脚本 storage.dfx

A B
1 =mongo_open("mongodb://127.0.0.1:27017/raqdb") / 连接 MongDB 数据库
2 =mongo_shell(A1,"storage.find()").fetch() / 获取集合 storage 数据
3 =A2.new(_id, name,   items.select(category=="food"):items ) / 过滤查询数据,将结果集存入序表
4 >A1.close() / 关闭连接
  2.      执行脚本返回结果:
A3 _id name items
1000 Storage   Alpha [[food,apple],[food,banana]]
1001 Storage   Beta [[food,pear],[food,peach],[food,grape]]

集算器提供了 JDBC 接口,脚本 storage.dfx 很容易集成到 Java 中:

public static void doWork() {
    Connection con = null;
    java.sql.Statement st;
   
    try{
        Class.forName("com.esproc.jdbc.InternalDriver");
        con = DriverManager.getConnection("jdbc:esproc:local://"); 
        // 调用脚本 storage.dfx
        st=con.createStatement(); 
        ResultSet rst = st.executeQuery("call storage");
        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 脚本》。