spring mongodb MapReduce添加scope,scope属性为函数时无法执行.

wonailmy 发布于 08/06 18:01
阅读 55
收藏 0

直接上mongodb脚本(隐藏部分业务代码,保留脚本结构)

db.behavior.mapReduce(function() {
    var bh = this;
    emit(key,values);
}, function(key, values) {
    //我的业务
    //调用自定义函数
    return ana("a", "b", "c");
}, {
    out: "report-20190729",
    jsMode: true,
    query: {
        startTime: {
            $gte: ISODate('2019-07-29 00:00:00'),
            $lte: ISODate('2019-07-29 23:59:59')
        }
    },
    finalize: function(k, v) {
        return v;
    },
    scope: {
        //自定义的一些函数
        ana: function(a, b, c) {
            var obj = {};
            //大量业务实现
            return obj;
        },
        distinct: function(a) {
            var result = [];
            //大量业务实现
            return result;
        },
        disTime: function(text) {
            if(!text) return null;
            //大量业务实现
            return text;
        },
        push: function(event, prev) {
            //大量业务实现
        },
        pushObj: function(event, prev, leaf) {
            //大量业务实现
        }
    }
});
  • 问题描述

想通过mongodb提供的MapReduce来进行数据分析,然后动态写入Collection中.以上代码脚本可以直接运行在mongodb中,但当我想用spring mongodb去实现时候却出现问题.

关键点在于,运用了scope,将scope的属性定义为函数.然后在map/reduce/finalize函数中去调用(想的是将一些公共逻辑封装起来).但是使用spring来实现的时候会报自定函数不是function.

代码如下:

Criteria c = new Criteria();
        c.andOperator(Criteria.where("startTime").gte(start.toDate()),Criteria.where("startTime").lte(end.toDate()));
Query query = Query.query(c);
String outCollectionName = "report-20190505";
//Map映射函数
String mapFunction = mjUtil.getCommand("day/map.js");
//统计化简函数
String redFunction = mjUtil.getCommand("day/red.js");
//最终处理函数
String finalizeFunction = mjUtil.getCommand("day/finalize.js");
//自定义函数,存放在作用域中
Map<String, Object> scope = new HashMap<>();
scope.put("ana",mjUtil.getCommand("day/ana.js"));
scope.put("distinct",mjUtil.getCommand("day/distinct.js"));
scope.put("disTime",mjUtil.getCommand("day/disTime.js"));
scope.put("push",mjUtil.getCommand("day/push.js"));
scope.put("pushObj",mjUtil.getCommand("day/pushObj.js"));

MapReduceOptions options = MapReduceOptions.options();
options.finalizeFunction(finalizeFunction);
options.outputCollection(outCollectionName);
//指定采用JS方式传输对象,数据量大情况下如果采用BSON,数组会被分割传输
options.javaScriptMode(true);
options.scopeVariables(scope);
mongoTemplate.mapReduce(query,"behavior",mapFunction,redFunction,options,Document.class);

其中将各个函数分别封装到一个js文件中去,通过mjUtil.getCommand("day/ana.js")调用获取到String类型的js代码.

错误信息如下:

on server 192.168.0.109:27017. The full response is { "ok" : 0.0, "errmsg" : "TypeError: ana is not a function :\nred@:10:12\n@:1:121\n", "code" : 139, "codeName" : "JSInterpreterFailure" }

希望大神来指教下,为什么!是不是spring mongodb不支持scope属性为函数?

加载中
返回顶部
顶部