MongoDB 怎么实现行列转换

因业务需求,在 MongoDB 使用中需要处理行列转换。如有集合 scores, 记录了学生English、Math、PE三科成绩,需将 English、Math、PE 各科成绩分别作为列值显示。

CLASS   STUDENTID       SUBJECT SCORE
Class one 1 English 84
Class one 1 Math 77
Class one 1 PE 69
Class one 2 English 81
Class one 2 Math 80
期望输出如下:
CLASS   STUDENTID English Math PE
Class   one 1 84 77 69

由于 MongoDB 没有提供相应的 api,实现按分组方式处理,但操作起来比较麻烦。

可以使用集算器, 用 pivot 函数实现比较容易。
集算器安装包可去润乾网站下载,运行时需要一个授权,免费版本就够用。

我们将上述事例实现步骤:

1、在集算器中编写脚本 scores.dfx

A B
1 =mongo_open("mongodb://127.0.0.1:27017/raqdb") / 连接 MongDB 数据库
2 =mongo_shell(A1,"scores.find(,{_id:0})") / 获取集合 scores 数据
3 =A2.pivot(CLASS,STUDENTID;SUBJECT,SCORE) / 将成绩实现行转换成列
4 =A3.pivot@r(CLASS,STUDENTID;SUBJECT,SCORE) / 将成绩实现列转换成行
5 >A1.close() / 关闭连接
  2、 执行脚本返回结果:
A3 CLASS   STUDENTID English Math PE
Class   one 1 84 77 69
Class   one 2 81 80 97
Class   one 3 75 86 67
A4 CLASS   STUDENTID SUBJECT SCORE
Class   one 1 English 84
Class   one 1 Math 77
Class   one 1 PE 69
Class   one 2 English 81
Class   one 2 Math 80

pivot()函数按给定的 CLASS, STUDENTID 字段分组,将 SUBJECT 中的值作为列字段,SCORE 根据新列字段进行对应输出,即实现行转换成列pivot@r()则实现列转换成行。

集算器提供了 JDBC 接口,脚本 scores.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://"); 
        // 调用脚本 scores.dfx
        st=con.createStatement(); 
        ResultSet rst = st.executeQuery("call scores");
        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 脚本》。