3

CouchDB にあるデータを集計しようとしています。データベースには写真ドキュメントと評価ドキュメントがあります。各評価ドキュメントは次のようになります (sans _id および _rev):

{
   "type": "rating",
   "rating": 3 // Integer values are identifiers that map to a string; e.g 1 might mean 'funny'
   "photo": "as9i83ufsafa09uj" // The id of the photo that this rating points to.
}

私がやりたいのは、各写真の各評価タイプのカウントを取得することです。

{
   "key": "as9i83ufsafa09uj", "value": [1, 7, 8, 6] // 1 '0' rating, 7 '1' ratings, etc.
   "key": "photoid2", "value": [3, 0, 0, 8]
}

この集約を実現するために、CouchDB ビューの MapReduce を使用しています。

"map": "function(doc) {
   if(doc.type == 'rating')
   {
      emit(doc.photo, doc.rating);
   }
}",

"reduce": "function(keys, values, rereduce) {
   var result = new Array(0, 0, 0, 0);

   values.forEach( function(key, value)
   {
      result[value]+=1;
   });

   return result;
}"

マップは次を返します。

{"total_rows":55,"offset":0,"rows":[
{"id":"0aa2c4c9a031eedbcf2795cabc1679be","key":"4aa5ec26-26b8-490a-a9cc-620a0d2136b9","value":0},
{"id":"29f363432e008f5934b4160292e18680","key":"4aa5ec26-26b8-490a-a9cc-620a0d2136b9","value":3},
{"id":"646d0d764623bc2f3ed1354ac03b583e","key":"4aa5ec26-26b8-490a-a9cc-620a0d2136b9","value":2},
...
{"id":"fa5be78402171e3bf1eb1cf91c5fda6e","key":"c63b78b6-ad92-426c-ab64-c9a6ae229b31","value":1}
]}

reduce は、witb group_level=0 を返します。

{"rows":[
{"key":null,"value":[1,1,1,1]}
]}

group_level=1 の場合:

{"rows":[
{"key":"4aa5ec26-26b8-490a-a9cc-620a0d2136b9","value":[2,2,2,0]},
{"key":"5ad3de4b-d25b-42d3-95e0-df7661becbf3","value":[2,2,2,2]},
{"key":"7600710b-9ae3-4312-876c-ad352722dac3","value":[2,2,2,2]},
{"key":"959f48a2-5018-4938-aab4-086d8824dd75","value":[2,0,0,0]},
{"key":"c63b78b6-ad92-426c-ab64-c9a6ae229b31","value":[2,2,2,2]}
]}

私は MongoDB の map reduce に精通しており、この関数はそのスキーマを使用して機能します。これを CouchDB で機能させるには、何を微調整する必要がありますか?

UPDATE これは、私のために働いた最終的なreduce関数です。rereduce パラメータに正しく対処していませんでした。rereduce の理解を深める手助けをしてくれた Marcin Skórzewski に感謝します。

"reduce": "function(key, values, rereduce) {

        var result = new Array(0, 0, 0, 0);

        if(rereduce == true)
        {
            for(var i = 0; i < values.length; i++)
            {
                var value = values[i];

                for (var j = 0; j < value.length; j++)
                {
                    result[j] += value[j];
                }
            }

            return result;
        }

        for(var i = 0; i < values.length; i++)
        {
            value = values[i];
            result[value]+=1;
        }

        return result;

        }"
4

1 に答える 1

3

使い方が間違っていると思いますrereducevalues要素と返されたデータが同じ型ではありません。グループ レベルが 1 つだけでデータのサイズが小さい場合 (単一の B ツリー ノードに収まるように)、rereduce を実行する必要がないため、問題なく動作します。reduce docrereduceと の引数の意味を見てくださいreduce()

reduce()から出力された値に対して実行される場合、map()それらは整数ですが、以前に取得した値を減らすと、reduce()それらは配列になります。配列を追加するrereduce場合は and を利用できます。trueまたは、 map で配列を発行して (たとえば、[0,0,0,1]の代わりにget する)、引数を気にせず3に常に配列を追加することもできます。reduce()rereduce

于 2012-10-12T08:52:11.107 に答える