1

大きなコレクションを小さな断片に集約し、それらをタイムスタンプでグループ化するために使用する python-script ウィッチに問題があります。

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) は任意の分数でグループ化する必要があります。http://jsfiddle.net/QgMzK/1/でJavascript をテストしましたが、問題なく動作するようです。しかし、Python で実行すると、すべてのタイムスタンプが ISODate("1970-01-01T00:00:00Z") になります。

何か案は?

4

1 に答える 1

3

マップ関数は 1 つのパラメーターを受け取ります。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}

ts結果にあることに注意してくださいNone。原因numberは、マッピング関数が実行されたときに設定されませんでした。

編集 2

私の知る限り、パラメーターを渡す唯一の方法は、でオプションのパラメーターmapを使用することですが、とにかくマップ署名からそれを削除する必要があります。scopemap_reduce

したがって、マップを次のように変更します。

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

望む結果を得ることができます。

于 2012-08-15T08:55:45.683 に答える