MongoDB 记录的字段不同时如何合并求和

本文介绍了如何在MongoDB中处理字段不一致的文档进行分组统计。通过示例数据展示了利用MongoDB脚本实现的复杂过程,并提出使用集算器简化这一操作,通过编写脚本实现数据整理、分组求和及行列转换。集算器的JDBC接口使得脚本易于集成到Java应用中。

MongoDB数据库采用bson的格式存储,存储的内容是文档型的。每一条记录就是一个文档,每个文档中的键不一定相同,键的个数也不一定相等,对这样嵌套的文档结构关系,进行分组统计就比较麻烦。比如有以下数据集
{"name": "test","num": {"text": 1,"face": 2}},
{"name": "test","num": {"image": 3,"face": 4}},
{"name": "test","num": {"text":5,"image": 6, "book": 12}},
{"name": "demo","num": {"text": 3,"face": 4}},
{"name": "demo","num": {"image": 7,"face": 8}},
{"name": "demo","num": {"text":5,"image": 5}}
 
希望获得各产品数量,查询结果为:
{"_id" : "test",  "count" : { "image" : 9, "book" : 12, "face" : 6, "text" : 6} }
{"_id" : "demo", "count" : { "image" : 12, "text" : 8, "face" : 12} }

用 MongoDB 脚本实现思路,先将 num 作为数组拆开,转换成文档分别统计,完成后重新分组过滤显示,实现比较复杂。

使用集算器,将数据整理成序表,通过序表分组求和, 再行列转换就可以,这样就方便得多了。

我们将上面描述实现步骤:
1.    在集算器中编写脚本 test.dfx:

AB
1=mongo_open("mongodb://localhost:27017/cookie  ")/ 连接数据库
2=mongo_shell(A1,"test.find( {},   {_id: 0})").fetch()/ 查询集合 test
3=A2.(~.(( d=num.array(),   num.fname().( name|~| d(#)) )).conj())/ 将 num 下的字段与其及对应
4=create(NAME, SNAME,   NUM).record(A3.conj())/A3 记录存储新序表
5=A4.groups(NAME, SNAME; sum(NUM):   COUNT)/ 按 NAME,SNAME 分组对 num 求和
6=A5.pivot(NAME;SNAME,COUNT)/ 进行行列转换, 将 SNAME,COUNT 行变成列
7>mongo_close(A1)/ 关闭连接


2.    调试执行一下,可以看到 A3 的格值为

A3Member
[test,text,1.0,…]
[test,image,3.0,…]


> 其它格值就不再一一列出。
3.    执行脚本返回结果:

A6NAMEbookfaceimage
demo(null)12.012.0
test12.06.09.0

A3中把 NUM 下的列名与其值对应,再与 NAME 组成一条条记录, A4 将记录存入序表;对序表分组求和再进行行列转换。

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

public static void doTest() {
    Connection con = null;
    java.sql.Statement st;
   
    try{
        Class.forName("com.esproc.jdbc.InternalDriver");
        con = DriverManager.getConnection("jdbc:esproc:local://"); 
// 调用 test.dfx 脚本
        st=con.createStatement(); 
ResultSet rst = st.executeQuery("call test");
        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、付费专栏及课程。

余额充值