Javascript MongoDB MapReduce、日期和%运算符
我的python脚本有一个问题,我使用它将大型集合聚合成较小的片段,并按时间戳对它们进行分组Javascript MongoDB MapReduce、日期和%运算符,javascript,python,mongodb,mapreduce,Javascript,Python,Mongodb,Mapreduce,我的python脚本有一个问题,我使用它将大型集合聚合成较小的片段,并按时间戳对它们进行分组 map = Code("function(number) {" "emit({" "ts : new Date(new Date((this.ts - (this.ts % (60 * number))) * 1000).setSeconds(0))" "}, 1);" "}") reduce = Code("function(key, vals) {" "var
map = Code("function(number) {"
"emit({"
"ts : new Date(new Date((this.ts - (this.ts % (60 * number))) * 1000).setSeconds(0))"
"}, 1);"
"}")
reduce = Code("function(key, vals) {"
"var sum = 0;"
"for (var i in vals) {"
"sum += vals[i]"
"}"
"return sum;"
"}")
如您所见,这是一个非常简单的MapReduce,时间戳(ts)应该按给定的分钟数分组。我在这里测试了Javascript,它似乎工作得很好。但当我在Python中运行它时,所有的时间戳都变成了ISODate(“1970-01-01T00:00:00Z”)
有什么想法吗?您的map函数采用一个参数:
number
,当map reduce调用该参数时,该参数将设置为null,并且在coertion(一些%
为零)之后,将使您的map返回的日期为ISODate(“0NaN:NaN:NaNZ”)
。在类型转换之后,它将变成datetime.datetime(1970,1,1,0,0)
删除该参数,它应该可以工作
编辑
要确认这一点,请尝试运行以下代码:
from pymongo import Connection
from bson.code import Code
db = Connection().mr_test
for i in xrange(10):
db.things.insert({"x" : i})
map = Code("function(number) {"
"emit({"
"ts : number"
"}, 1);"
"}")
reduce = Code("function(key, vals) {"
"var sum = 0;"
"for (var i in vals) {"
"sum += vals[i]"
"}"
"return sum;"
"}")
result = db.things.map_reduce(map, reduce, "test_results")
for doc in result.find():
print doc
我的机器上的结果是:
{u'_id': {u'ts': None}, u'value': 10.0}
请注意,ts
在结果中为None
,原因是执行映射函数时未设置number
编辑2
AFAIK将参数传递给map
的唯一方法是使用map\u reduce
中的scope
可选参数,但您仍必须将其从map签名中删除
因此,通过将地图更改为:
map = Code("function() {"
"emit({"
"ts : new Date(new Date((this.ts - (this.ts % (60 * number))) * 1000).setSeconds(0))"
"}, 1);"
"}")
并致电:
db.whatever.map_reduce(map, reduce, "collection_name", scope = {"number" : the_value_your_function_needs})
您可以得到所需的结果。映射函数的数字参数是,这样我就可以按最接近的5、10或X分钟对集合进行分组。如果我将ts prop更改为ex,ts:number@Jarsäter这很奇怪,因为据我所知,它返回
None
作为map reduce结果中的唯一键,这与我的答案完全一致。