db.runCommand(
{ mapreduce : <collection>,
map : <mapfunction>,
reduce : <reducefunction>
[, query : <query filter object>]
[, sort : <sort the query. useful for optimization>]
[, limit : <number of objects to return from collection>]
[, out : <output-collection name>]
[, keeptemp: <true|false>]
[, finalize : <finalizefunction>]
[, scope : <object where fields go into javascript global scope >]
[, verbose : true]
}
);
其中的query 真的是一个关键词。
map = function() {
emit(this.query, this.cnt);
};
reduce = function(key , vals) {
var sum = 0;
for(var i in vals) {
sum += vals[i];
}
return sum;
};
res = db.log_info.mapReduce(map,reduce,{"query":{"year":2010}});
看到没有:query 关键词为过滤记录的。必须有这个词:代表 后面的对象为查询对象
之前没有仔细阅读mongodb的文档,结果弄出一个笑话:
res = db.Flow.mapReduce(map,reduce,{"userid":"7l8dued9ot"});
这样是错误的,以为 将查询条件包装为一个bson数据就可以了。这样的话 得出的结果为全部数据。也就是 条件过滤没有生效。
接下来一个bug我更怒火。完全将自己对mongodb的不熟悉表现出来了。
过年前做的一个首页统计功能。发现近30天的数据统计和统计全部是一样的。开始没有怎么的注意 毕竟 这是测试数据。后来发现是有问题的。就是不知哪里出问题了。
觉得mongodb的代码没有问题。特别是mapreduce,执行命令是正确的,可是变成代码就出问题了。
昨晚去酒吧喝完酒后,回到宿舍想起了这个bug。睡觉的 时候 心里暗暗的想明天要解决这个bug。
经过一系列的google和baidu后。发现了问题所在:
query.put("longtime", new BasicDBObject("$gte", start));
query.put("longtime", new BasicDBObject("$gte", end));
我的本意是 做到 大于start 而少于end的数据进行统计的。
可是上面的语法是错误的。
错误mongodb 并没有说什么错误,还是帮我执行了,但是结果是 query没有起筛选记录的作用。统计出的结果还是全部记录。
正确的写法:
query.put("longtime", new BasicDBObject("$gte", start).append("$lte", end));
这才是 找出大于start 而少于end的记录。