MongoDB 如何合并相同属性的不同字段

MongoDB作为文档型数据库,可方便灵活存储文档,属性相同或相似的数据可采用不同的形式来记录。如有集合 users, 其中用户 July 与 Tom 电话字段记录方式不同,一个多字段形式,一个数组形式,希望按 NAME 分组,合并其下的 TEL。具体数据如下:

  ……
  {
    "_id" : ObjectId("5fd305b4db8950e48f0cf196"),
    "username" : "July",
    "gender" : "F",
    "age" : 17,
    "TEL1" : "18811223298",
    "TEL2" : "18581418158",
    "TEL3" : "15286856439"
}

{
    "_id" : ObjectId("5fd30828db8950e48f0cf197"),
    "username" : "Tom",
    "gender" : "M",
    "age" : 15,
    "TEL" : [
        "13800226298",
        "18511418100",
        "13986666413"
    ]
}
……

用 MongoDB 脚本实现思路,可先获取集合的字段名,再根据字段名匹配获取对应的电话字段,再将电话字段数据合并,使用mapreduce遍历处理,实现过程比较烦琐。

使用集算器, 可先找到 TEL 相关的字段,再将其对应的值合并,实现比较容易。
集算器安装包可去 润乾网站 下载,运行时需要一个授权,免费版本就够用。

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

A B
1 =mongo_open("mongodb://localhost:27017/local") / 连接 MongDB 数据库
2 =mongo_shell(A1,"users.find(,{_id:0})") / 获取集合 users 数据
3 =A2.fname().pselect@a(like(~, "TEL*")) / 找出以 TEL 开头的字段对应的列号
4 =A2.new(username, gender, age, (   t=~.array(), A3.conj(t(~))\[null] ):tels) / 将电话号码合并,去掉空值,存入新序表的 TELS 字段
5 >A1.close() / 关闭连接
  2.      调试执行一下:可看到 A3 格值为:
A3 Member
5
6
……
  3.      执行脚本返回结果:
A4 username gender age tels
July F 17 [18811223298,185814…]
Tom M 15 [13800226298,185114…]

A4:将记录数据存入变量 t,根据电话所在列的序号获取对应的电话号码,再合并。

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