0

私は MongoDB を使用しており、コレクション内の個別の「concatenated_handles」(文字列型のフィールド) の出現回数を数えたいと考えていました。

発生回数にも応じてソートする必要があったため、mapreduce を使用することにしました。すべてうまくいったのですが、突然予期しない結果が得られ始め、コードをまったく変更しませんでした。

これは私の地図です:

function() { emit(this.concatenated_handles, { count: 1}); }

これは reduce です:

r = function(key, values) { var result = {count : 0}; values.forEach(function(value) { result.count++; }); return result; }

一部のフィールドでは正しい値を返しますが、他のフィールドでは正しくありません。出力をログに記録しました。ここにあります(バグのあるフィールドのみを表示)

    msdhoni#yuvstrong12:0
    msdhoni#yuvstrong12:1
    msdhoni#yuvstrong12:2
    ....
    ...
    msdhoni#yuvstrong12:255
    msdhoni#yuvstrong12:256
    musclenerd#pod2g:0
    musclenerd#pod2g:1

このフィールドは、他の数行の後に再びグループ化を開始します (すべての再グループ化は最後に向かっています)

justinbieber#pattiemallette:0
justinbieber#pattiemallette:1
justinbieber#pattiemallette:2
justinbieber#pattiemallette:3
justinbieber#scooterbraun:0
justinbieber#scooterbraun:1
justinbieber#scooterbraun:2
kaleycuoco#kunalnayyar:0
kaleycuoco#kunalnayyar:1
kaleycuoco#kunalnayyar:2
kaleycuoco#kunalnayyar:3
kaleycuoco#kunalnayyar:4
kaleycuoco#kunalnayyar:5
msdhoni#yuvstrong12:0
msdhoni#yuvstrong12:1
msdhoni#yuvstrong12:2

上記のすべてのフィールドは、最後に向かって再グループ化されます。それらは同じように見えますが、2 回グループ化されたため、予期しない結果になりました。そして、これはすべてのレコードで発生するわけではありません。

どこが間違っていますか?グループ フィールドは文字列です。

ありがとう!

4

1 に答える 1

0

さて、MongoDB は MapReduce を再帰的に、または部分的に呼び出すことができます。したがって、reduce 関数はべき等でなければなりません。

値マップの構造が出力され、reduce が返す値の構造が同じであるため、私の reduce 関数も冪等であると言えます。ただし、注意すべき非常に重要な点が 1 つあります。呼び出しが繰り返し行われる場合は常に、最初の呼び出しの結果が 2 番目の呼び出しへの入力として渡されます。

したがって、私の場合、この reduce :

r = function(key, values) { var result = {count : 0}; values.forEach(function(value) { result.count++; }); return result; }

同じキーに対する後続のすべての呼び出しは、前の反復から value.count として渡されたカウントを追加する代わりに、0 からインクリメントを開始し、1 を追加します。

だから代わりに

result.count++; 

やってるはずだった

result.count += value.count;

すべての呼び出しが前の呼び出しまでのカウントを使用するようにします。

これを正しく説明したかどうかはわかりませんが、ここに十分に文書化されています(詳細な技術的説明の下):

http://www.mongodb.org/display/DOCS/MapReduce

于 2012-07-05T22:36:11.433 に答える