5

Mongo db で map reduce ジョブを実行しています。

マッピング関数は、特定の性質のイベントを特定のタイム ゾーンの日付にマップ (カウントなど) する必要があります (マップのキーは暦日です)。タイムゾーンは異なっていてもかまいませんが、実際には map/reduce ジョブへの入力パラメーターです。

データベース オブジェクトに保存される時間は UTC です。

例:

object1: time=78000
object2: time=86420

mapReduce(objects, tz='America/Los_Angeles')
would return: [{"1/1/1970" : 2}]

mapReduce(objects, tz='Europe/London')
would return: [{"1/1/1970":1},{"1/2/1970":1}]

同じデータセットで。

JavaScript の Date オブジェクトは、任意の UTC 時間を現地時間に完全に変換できますが、J/S 環境の「現在の」タイム ゾーンに限定されているようです。変換したいタイムゾーンを指定する方法が見つからないようです。

変換では DST を考慮する必要があり、できればうるう秒を考慮する必要があります。

これを達成するために私にできることはありますか?

4

1 に答える 1

5

私のために働く答えを見つけました。結局のところ、スコープはサーバー側の mongo DB でのこのサポートに限定されており、Linux のみでした。

@AsyaKamsky は、IANA の実際のタイム ゾーン ファイルを使用することを考慮して、完全かつ適切なタイム ゾーンをサポートする素晴らしい J/S ライブラリtimezone-jsを指摘しました。ただし、任意の Java スクリプト ライブラリを Mongo サーバー環境にロードするのはそれほど簡単ではありません。グローバル関数定義のみをロードできます。timezone-jsには、タイムゾーン ファイルをダウンロードするためのカスタム トランスポート メカニズムも提供する必要があります (MongoDB サーバー環境がファイル アクセスを提供しているかどうかさえわかりません)。または、タイム ゾーン ファイルを JSON オブジェクトにプリコンパイルし、一緒に提供する必要があります。ライブラリと。私は、これは面倒なアプローチだと判断し、タイム ゾーン ファイルが変更されたときにそれを更新するメカニズムを提供する責任を負う必要があると判断しました。

私が検討していたもう 1 つの選択肢は、Mongo で使用されている J/S 実装をハッキングして、やりたいことを実行する関数を追加することです。それが私がしたことです。実際、glibc の世界でも JavaScript の世界と同じくらい悲惨な状況ですが、この仕事のためのライブラリicuがあります。

UTC タイムスタンプとタイムゾーン名を取得し、yyyy-mm-dd 文字列を返す静的な Date.daytz() 関数を追加するこのパッチを作成しました。

次の map/reduce 関数を考慮します。

fmap = function () {
    emit(Date.daytz(this.time * 1000, globtz), {count:1});
};
fred = function (k, v) {
    var r = {count:0};
    v.forEach(function (v0) {r.count += v0.count;});
    return r;
};

次の 2 つの map reduce コマンドを実行して、まさに私が望んでいたものを取得しました。

{ "mapreduce" : "objects",
    "map" : fmap,
    "reduce" : fred,
    "out" : { "inline" : 1 },
    "scope" : { "globtz" : "Europe/London" } }

{ "mapreduce" : "objects",
    "map" : fmap,
    "reduce" : fred,
    "out" : { "inline" : 1 },
    "scope" : { "globtz" : "America/Los_Angeles" } }
于 2012-10-12T19:58:45.813 に答える