0

データがロードされた4つのriakノードのクラスターがあります。集約するだけの単純なMapReduceジョブを実行しようとしていますが、独自のjavascript関数を提供することで実行しようとしています(より複雑なMapReduceジョブに移動するため)。

私の関連するJavaスニペットは次のとおりです。

IndexQuery iq = new IntRangeQuery(IntIndex.named(indexId), bucketId, 11, 40);
Function mapfunc = new JSSourceFunction(
    streamToString(MapReduceDriver.class.getResourceAsStream("/map_1.js")));
Function redfunc = new JSSourceFunction(
    streamToString(MapReduceDriver.class.getResourceAsStream("/reduce_1.js")));
PBMapReduceResult result = (PBMapReduceResult) riakClient.mapReduce(iq)
            .addMapPhase(mapfunc)
            .addReducePhase(redfunc)
            .execute();

2つのjavascript関数は次のとおりです。

function map_keepAttr(value, keyData, arg) {
    var data = Riak.mapValuesJson(value)[0];
    return [ data.Attribute_17 ];
}

function reduce_aggregate(values, arg) {
    return [values.length];
}

私が見ている問題は次のとおりです。クエリとマップフェーズによって生成される値は正確に30個あります。ただし、reduceフェーズでは30ではなく3が報告されます(したがって、正しくカウントされません)。さらに奇妙なのは、次のreduce関数を使用すると次のようになることです。

function reduce_aggregate(values, arg) {
    return values.length;
}

期待どおりの結果、つまり正確に30個のエントリを含むjson配列が得られます。

RiakのMapReduceがどのように機能するかわからないように見えるので、どんな助けでも私を救うでしょう。

ありがとう!

4

1 に答える 1

1

表示されている問題は、reduceフェーズ関数でre-reduceを考慮していないことが原因である可能性があります。

マップフェーズ関数はレコードごとに1回実行されますが、リデュースフェーズ関数は必ずしも完全なデータセットを入力として1回実行されるとは限りません。代わりに、すべてのレコードが処理されるまで、マップフェーズ出力の一部に対して再帰的に実行されます。reduce関数の最初の実行によって作成された結果は、次の呼び出しに送信される配列に含まれます。

削減機能を使用してアイテムの数をカウントするには、以前の削減機能の結果をマップフェーズ入力から区別するか、データがどこにあるかに関係なく、同じ形式で正しく集計できることを確認する必要があります。から。

于 2012-11-08T14:50:33.113 に答える