MongoDB MapReduce, Date and % operator



我有一个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 sum = 0;"
    "for (var i in vals) {"
        "sum += vals[i]"
    "}"
    "return sum;"
"}")

如您所见,这是一个非常简单的MapReduce,时间戳(ts)应该按给定分钟数的anny分组。我已经在这里测试了Javascript http://jsfiddle.net/QgMzK/1/它似乎工作正常。但是当我在 Python 中运行它时,所有时间戳都变成了 ISODate("1970-01-01T00:00:00Z")。

有什么想法吗?

你的map函数接受一个参数:number,当map-reduce调用时,它将设置为null,并且在强制(和一些%为零)之后,将使地图返回的日期ISODate("0NaN-NaN-NaNTNaN: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}

请注意,结果中None ts,因为执行映射函数时未设置number

编辑 2

AFAIK 将参数传递给map的唯一方法是在map_reduce中使用scope可选参数,但无论如何您都必须将其从地图签名中删除。

因此,通过将地图更改为:

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}) 

你可以得到你想要的结果。

相关内容

  • 没有找到相关文章

最新更新