1

私たちの MongoDB データベースには、すべてのユーザー アカウントのリストが含まれており、新しい登録ごとに、アカウント ドキュメントに、作成された現在の日時を含む 'created_at' フィールドがあります。

1 日あたりの新規登録数を知りたかったので、MapReduce クエリをまとめてこれを調べました。

db.accounts.mapReduce(
    function() { 
        var date = this.created_at.toLocaleDateString(); 
        emit(date, 1);
    }, 
    function(key, values) {
        return values.length;
    },
    { out: "output" })

最初の試みは以上でした。登録ごとに1、その日付の値を発行します。次に、各配列の長さを使用して、その日にあった登録数を特定します。

ただし、結果はほぼ正しいものでしたが、顕著な不正確さがありました。たとえば、実際の数値がはるかに高いことがわかっている場合、初日は 2 桁の数値が表示されます。同じデータを操作しているにもかかわらず、map reduce 関数を 2 回実行すると、一部の値が変更されました。

代わりに、配列の値を合計するように関数を変更しました (覚えておいてください、配列は のみで構成されて1いるため、array.length.

db.accounts.mapReduce(
    function() {
        var date = this.created_at.toLocaleDateString(); 
        emit(date, 1);
    }, 
    function(key, values) {
        var sum = 0; 
        for(var i = 0; i < values.length; i++) { 
            sum += values[i];
        }; 
        return sum; 
    },
    { out: "output" })

驚いたことに、これにより、以前は間違っていたすべての日付に対して正しい結果が得られました。

最初の map reduce が意図したとおりに機能しなかった理由を知っている人はいますか?

4

1 に答える 1

2

放出された値に対してReduceが複数回呼び出され、後の呼び出しに前の呼び出しの出力が渡されて、reduceが渡される場合があります。配列の長さだけを見ると、部分的に集約されたデータを見ている可能性があるという事実を見逃しています。値を合計すると、以前の集計が累積されます。これは必要なことです。

于 2012-05-23T16:46:59.917 に答える