MongoDB的脚本操作 - Map/Reduce、Script、Group的使用

MongoDB支持javascript脚本的解析。可以简化一些数据聚合、或一些脚本特殊处理。下面我们验证一下JAVA环境下调用脚本的操作。包括map/reduce操作,执行script操作,以及group的操作。

初始化数据对象

 

    public static final String COLLECTION_NAME = "jmr1";
    public static final String GROUP_TEST_COLLECTION = "group_test_collection";
    @Autowired
    private MongoOperations mongoOps;

    @Before
    public void setUp(){
        // 为map/reduce操作准备数据
        mongoOps.dropCollection(COLLECTION_NAME);
        final Jmr jmr1 = new Jmr(new String[]{"a", "b" });
        final Jmr jmr2 = new Jmr(new String[]{"b", "c" });
        final Jmr jmr3 = new Jmr(new String[]{"c", "d" });
        mongoOps.insert(Lists.newArrayList(jmr1,jmr2,jmr3), COLLECTION_NAME);
        // 为group操作准备数据
        mongoOps.dropCollection(GROUP_TEST_COLLECTION);
        final X x1 = new X(1);
        final X x2 = new X(1);
        final X x3 = new X(2);
        final X x4 = new X(2);
        final X x5 = new X(3);
        final X x6 = new X(3);
        mongoOps.insert(Lists.newArrayList(x1,x2,x3,x4,x5,x6), GROUP_TEST_COLLECTION);
    }


    @Data @AllArgsConstructor @NoArgsConstructor
    class X{
        int x ;
    }

    @Data
    class XObject {

        private float x;

        private float count;

        @Override
        public String toString() {
            return "XObject [x=" + x + " count = " + count + "]";
        }
    }

@Data @AllArgsConstructor @NoArgsConstructor
class Jmr {
    String[] x;
}

@Data
class ValueObject {

    private String id;
    private float value;

    @Override
    public String toString() {
        return "ValueObject [id=" + id + ", value=" + value + "]";
    }
}

Map/Reduce 数据聚合

1、摘录了一个思路图

 

Map/Reduce思路

2、 准备map.js脚本

 

function () {
    for (var i = 0; i < this.x.length; i++) {
        emit(this.x[i], 1);
    }
}

3、准备reduce.js脚本

 

function (key, values) {
    var sum = 0;
    for (var i = 0; i < values.length; i++)
        sum += values[i];
    return sum;
}

4、执行map/reduce操作

 

    /**
     * map/reduce,用作数据聚合。
     * 脚本支持本地,或http
     */
    @Test
    public void testMapReduce(){
        MapReduceResults<ValueObject> results = mongoOps.mapReduce(
                "jmr1", "classpath:map-reduce/map.js", "classpath:map-reduce/reduce.js", ValueObject.class);
        for (ValueObject valueObject : results) {
            System.out.println(valueObject);
        }
        /**
         * 结果如下:
         * ValueObject [id=a, value=1.0]
         * ValueObject [id=b, value=2.0]
         * ValueObject [id=c, value=2.0]
         * ValueObject [id=d, value=1.0]
         */
    }

    /**
     * 设置查询条件,和输出collection。并 map/reduce
     */
    @Test
    public void testMapReduceByQueryAndOutput(){
        Query query = new Query(where("x").ne(new String[] { "a", "b" }));
        MapReduceResults<ValueObject> results = mongoOps.mapReduce(query,
                "jmr1", "classpath:map-reduce/map.js", "classpath:map-reduce/reduce.js",
                options().outputCollection("jmr1_out"), ValueObject.class);

        final List<ValueObject> jmr1_out = mongoOps.findAll(ValueObject.class, "jmr1_out");
        for (ValueObject valueObject : jmr1_out) {
            System.out.println(valueObject);
        }
    }

执行script脚本

MongoDB允许通过直接发送脚本或调用存储的脚本在服务器上执行JavaScript函数。

 

    @Test
    public void testScript(){

        ScriptOperations scriptOps = mongoOps.scriptOps();

        ExecutableMongoScript echoScript = new ExecutableMongoScript("function(x) { return x; }");
        // 直接执行脚本,而不将函数存储在服务器端。
        Object directly_execute_script = scriptOps.execute(echoScript, "directly execute script");
        Assert.assertEquals("directly execute script",directly_execute_script);
        // 使用'echo'作为脚本的名称来存储脚本。给定的名称标识脚本并允许稍后调用它。
        scriptOps.register(new NamedMongoScript("echo", echoScript));
        // 使用提供的参数执行名为“echo”的脚本。
        Object call = scriptOps.call("echo", "execute script via name");
        Assert.assertEquals("execute script via name",call);
    }

Group操作

Group操作,是相对于map/reduce的另外一种数据聚合方式。使用组操作确实有一些限制,例如在共享环境中不支持它,并且它在单个BSON对象中返回完整的结果集,因此结果应该很小,小于10,000个键。

 

    @Test
    public void testGroup(){
        GroupByResults<XObject> results = mongoOps.group(GROUP_TEST_COLLECTION,
                // 按x分组,设置文档值初始值{count:0}
                GroupBy.key("x").initialDocument("{ count: 0 }").reduceFunction("function(doc, prev) { prev.count += 1 }"),
                XObject.class);
        System.out.println(results.getRawResults().toString());
    }

结果如下:

 

Document {
    {
        retval = [Document {
            {
                x = 1.0, count = 2.0
            }
        }, Document {
            {
                x = 2.0, count = 2.0
            }
        }, Document {
            {
                x = 3.0, count = 2.0
            }
        }], count = 6, keys = 3, ok = 1.0
    }
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
为什么会这样[user_mongo@nosql01 replicaset]$ cd /opt [user_mongo@nosql01 opt]$ ll total 0 drwxr-xr-x. 3 root root 25 Mar 16 17:08 servers drwxr-xr-x. 2 root root 51 Mar 16 17:10 software [user_mongo@nosql01 opt]$ tar -zxvf /opt/software/mongodb-linux-x86_64-rhel70-4.4.12.tgz -C /opt/servers/mongodb_demo/replicaset/ mongodb-linux-x86_64-rhel70-4.4.12/LICENSE-Community.txt tar: mongodb-linux-x86_64-rhel70-4.4.12: Cannot mkdir: Permission denied tar: mongodb-linux-x86_64-rhel70-4.4.12/LICENSE-Community.txt: Cannot open: No such file or directory mongodb-linux-x86_64-rhel70-4.4.12/MPL-2 tar: mongodb-linux-x86_64-rhel70-4.4.12: Cannot mkdir: Permission denied tar: mongodb-linux-x86_64-rhel70-4.4.12/MPL-2: Cannot open: No such file or directory mongodb-linux-x86_64-rhel70-4.4.12/README tar: mongodb-linux-x86_64-rhel70-4.4.12: Cannot mkdir: Permission denied tar: mongodb-linux-x86_64-rhel70-4.4.12/README: Cannot open: No such file or directory mongodb-linux-x86_64-rhel70-4.4.12/THIRD-PARTY-NOTICES tar: mongodb-linux-x86_64-rhel70-4.4.12: Cannot mkdir: Permission denied tar: mongodb-linux-x86_64-rhel70-4.4.12/THIRD-PARTY-NOTICES: Cannot open: No such file or directory mongodb-linux-x86_64-rhel70-4.4.12/bin/install_compass tar: mongodb-linux-x86_64-rhel70-4.4.12: Cannot mkdir: Permission denied tar: mongodb-linux-x86_64-rhel70-4.4.12/bin/install_compass: Cannot open: No such file or directory mongodb-linux-x86_64-rhel70-4.4.12/bin/mongo tar: mongodb-linux-x86_64-rhel70-4.4.12: Cannot mkdir: Permission denied tar: mongodb-linux-x86_64-rhel70-4.4.12/bin/mongo: Cannot open: No such file or directory mongodb-linux-x86_64-rhel70-4.4.12/bin/mongod tar: mongodb-linux-x86_64-rhel70-4.4.12: Cannot mkdir: Permission denied tar: mongodb-linux-x86_64-rhel70-4.4.12/bin/mongod: Cannot open: No such file or directory mongodb-linux-x86_64-rhel70-4.4.12/bin/mongos tar: mongodb-linux-x86_64-rhel70-4.4.12: Cannot mkdir: Permission denied tar: mongodb-linux-x86_64-rhel70-4.4.12/bin/mongos: Cannot open: No such file or directory tar: Exiting with failure status due to previous errors [user_mongo@nosql01 opt]$ tar -zcvf /opt/software/mongodb-linux-x86_64-rhel70-4.4.12.tgz -C /opt/servers/mongodb_demo/replicaset/ tar: Cowardly refusing to create an empty archive Try `tar --help' or `tar --usage' for more information.
最新发布
06-01

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值