【发布时间】:2015-10-25 06:50:16
【问题描述】:
我是 mongodb 的新手,但这只是我的简单测试。 不幸的是,使用相同的 map/reduce 函数,我从 mongo 命令行和 pymongo 得到不同的结果...... Pymongo是3.0.3,mongodb是3.0
下面是命令行操作:
map = function(){
... var date = new Date('2015-07-30');
... emit(date,this)
... }
function (){
var date = new Date('2015-07-30');
emit(date,this)
}
reduce = function(key, values){
... var sum = {'new':0,'act':0,'channel_new':{},'ver_new':{},'channel_ver_new':{}};
... values.forEach(function(doc){
... sum.new += doc.new;
... sum.act += doc.act;
... var category = {"channel_new":1,"ver_new":1,"channel_ver_new":1};
... for(var item in category)
... {
... var t = Object.keys(doc[item]);
... for(var i in t){
... if(Object.keys(sum[item]).indexOf(t[i])!=-1){
... sum[item][t[i]] += doc[item][t[i]];
... }else{
... sum[item][t[i]] = doc[item][t[i]];
... }
... }
... }
... });
... return sum;
... }
function (key, values){
var sum = {'new':0,'act':0,'channel_new':{},'ver_new':{},'channel_ver_new':{}};
values.forEach(function(doc){
sum.new += doc.new;
sum.act += doc.act;
var category = {"channel_new":1,"ver_new":1,"channel_ver_new":1};
for(var item in category)
{
var t = Object.keys(doc[item]);
for(var i in t){
if(Object.keys(sum[item]).indexOf(t[i])!=-1){
sum[item][t[i]] += doc[item][t[i]];
}else{
sum[item][t[i]] = doc[item][t[i]];
}
}
}
});
return sum;
}
db.daily.mapReduce(map,reduce,{out:"wnitest"})
{
"result" : "wnitest",
"timeMillis" : 12,
"counts" : {
"input" : 2,
"emit" : 2,
"reduce" : 1,
"output" : 1
},
"ok" : 1
}
结果如下:
db.daily.find()
{ "_id" : ObjectId("55bef40cf6d9e26e37e3e37b"), "date" : ISODate("2015-07-06T00:00:00Z"), "new" : 1,
"channel_ver_new" : { "111_0500_00*#*0\uff0E9\uff0E0" : 2 }, "ver_new" : { "0\uff0E9\uff0E0" : 2 },
"channel_new" : { "111_0500_00" : 2 } }
{ "_id" : ObjectId("55bef40cf6d9e26e37e3e37d"), "date" : ISODate("2015-07-07T00:00:00Z"), "new" : 2,
"channel_ver_new" : { "111_0500_00*#*1\uff0E0\uff0E0" : 3 }, "ver_new" : { "1\uff0E0\uff0E0" : 3 },
"channel_new" : { "111_0500_00" : 3 } }
db.wnitest.find()
{ "_id" : ISODate("2015-07-30T00:00:00Z"), "value" : { "new" : 3, "act" : NaN, "channel_new" : { "11
1_0500_00" : 5 }, "ver_new" : { "0\uff0E9\uff0E0" : 2, "1\uff0E0\uff0E0" : 3 }, "channel_ver_new" :
{ "111_0500_00*#*0\uff0E9\uff0E0" : 2, "111_0500_00*#*1\uff0E0\uff0E0" : 3 } } }
>
这是我的python代码:
mapper = Code("""function(){
var date = new Date('2015-7-30');
emit(date,this);
}""")
reducer = Code("""function(key, values){
var sum = {"new":0,"act":0,"channel_new":{},"ver_new":{},"channel_ver_new":{}};
values.forEach(function(doc){
sum.new += doc.new;
sum.act += doc.act;
var category = {"channel_new":1,"ver_new":1,"channel_ver_new":1};
for(var item in category)
{
var t = Object.keys(doc[item]);
for(var i in t){
if(Object.keys(sum[item]).indexOf(t[i])!=-1){
sum[item][t[i]] += doc[item][t[i]];
}else{
sum[item][t[i]] = doc[item][t[i]];
}
}
}
});
return sum;
}
""")
db.daily.map_reduce(mapper,reducer,'weekly')
Here is result:
> db.weekly.find()
{ "_id" : ISODate("2015-07-29T16:00:00Z"), "value" : { "_id" : ObjectId("55bef4eaf6d9e26e37e3e380"),
"date" : ISODate("2015-07-06T00:00:00Z"), "new" : 1, "channel_ver_new" : { "111_0500_00*#*0\uff0E9\
uff0E0" : 2 }, "ver_new" : { "0\uff0E9\uff0E0" : 2 }, "channel_new" : { "111_0500_00" : 2 } } }
>
这是对 pymongo 的 map_reduce 的响应:
{u'timing': {u'total': 59, u'mapTime': 0, u'emitLoop': 57, u'mode': u'mixed', u'reduceTime': 0}, u'counts': {u'input': 1, u'reduce': 0, u'emit': 1, u'output': 1}, u'timeMillis': 59, u'ok': 1.0, u'result': u'weekly'}
reduce 为 0,为什么?
【问题讨论】:
-
好的。代码包含更好。您在这里发出
emit(date,this),这似乎有点多余,因为文档中的某处可能有一个“日期”字段。输入的文档结构是什么?您的映射器“输出”与减速器“输出”可能存在差异,这是一个常见的 mapReduce 错误。再次编辑以显示典型文档。 -
嗨,看看 db.daily.find() 输出,你说得对,它有 'date' 字段,我认为与此无关,当我更改为另一个时仍然相同.似乎 reduce 没有与 pymongo map_reduce 一起运行。
-
在您的问题上使用“编辑”链接。 cmets中没有代码或数据。
-
您是否会停止做出自己的假设,请发布您被要求提供的详细信息。如果每个人真正遇到问题都是因为您正在使用的软件中的“错误”,那么世界将陷入停顿。 99.9999% 的时间,问题出在您的代码中。这就是为什么我想查看原始文档格式以供输入。
-
嗨布莱克斯,已经添加了 db.daily.find() :-)