5

mongo シェルの mongodb で map reduce を実行しようとしています。何らかの理由で、reduce フェーズで、(1 つのキーではなく) 同じキーに対して複数の呼び出しが行われるため、間違った結果が得られます。私はこの分野の専門家ではないので、愚かな間違いをしている可能性があります。どんな助けでも感謝します。

ありがとう。

これは私の小さな例です:

私は10000のドキュメントを作成しています:

var i = 0;
db.docs.drop();
while (i < 10000) {
    db.docs.insert({text:"line " + i,index:i});
    i++;
}

次に、モジュール 10 に基づいて map-reduce を実行しています (したがって、各「バケット」で 1000 を取得することを除いて)

db.docs.mapReduce(
    function() { 
       emit(this.index%10,1);
    },
    function(key,values) {
       return values.length;
    },
    {
    out : {inline : 1}
    }
);

ただし、結果として次のようになります。

{
    "results" : [
        {
            "_id" : 0,
            "value" : 21
        },
        {
            "_id" : 1,
            "value" : 21
        },
        {
            "_id" : 2,
            "value" : 21
        },
        {
            "_id" : 3,
            "value" : 21
        },
        {
            "_id" : 4,
            "value" : 21
        },
        {
            "_id" : 5,
            "value" : 21
        },
        {
            "_id" : 6,
            "value" : 21
        },
        {
            "_id" : 7,
            "value" : 21
        },
        {
            "_id" : 8,
            "value" : 21
        },
        {
            "_id" : 9,
            "value" : 21
        }
    ],
    "timeMillis" : 76,
    "counts" : {
        "input" : 10000,
        "emit" : 10000,
        "reduce" : 500,
        "output" : 10
    },
    "ok" : 1,
}
4

1 に答える 1

6

Map/Reduce は本質的に再帰的な操作です。特に、関数の文書化された要件にreduceは、次のステートメントが含まれます。

MongoDB はreduce、同じキーに対して関数を複数回呼び出すことができます。この場合、そのキーの関数からの前の出力は、そのキーの次の関数呼び出しreduceへの入力値の 1 つになります。reduce

したがって、入力は、以前の呼び出しでカウントされた数にすぎないと想定する必要があります。次のコードは、実際に値を追加することでこれを行います。

db.docs.mapReduce(
    function() { emit(this.index % 10, 1); }, 
    function(key,values) { return Array.sum(values); }, 
    { out : {inline : 1} } );

は、配列を埋めるために使用される単なる数値ではなく、その値が考慮されるため、emit(key, 1)ある意味ではより理にかなっています。1

補足として、これがどれほど危険であるかに注意してください。より小さなデータセットの場合、エンジンが並列化は必要ないと判断したため、正しい結果が偶然得られた可能性があります。

于 2013-10-08T17:42:06.923 に答える