0

これはこの質問のフォローアップですHow to merge objects attributes from reduce to rereduce function in CouchDB

私は前の質問から受け入れられた答えに従っています。簡単に確認すると、これは私の JSON スキーマです。

{"emp_no": ..,
"salary": ..,
"from_date": ..,
"to_date": ..,
"type" : "salaries"}

{"emp_no": ..,
"title": ..,
"from_date": ..,
"to_date" : ..,
"type" : "titles"}

アクティブな各タイトルの平均給与を調べたい ("from_date" = "9999-01-01" で示される)。rereduce の出力は reduce の出力と同じでなければならないため、値は次の形式になります。

{"Title":[sum,count],"Title":[sum,count]}

そのフォームに基づいて、reduce 関数を前の質問から次のように変更しました。

function(keys, values, rereduce) {
    function isArray(o) {
      return Object.prototype.toString.call(o) === '[object Array]';
    }
    var i, l, sal, count, rv = {}, kobj;
    if (rereduce) {
        for (i = 0, l = values.length; i<l ; ++i) {
            if (i === 0) {
                for (kobj in values[i]) {
                    if(values[i].hasOwnProperty(kobj)) {
                        if (isArray(values[i][kobj]) ) {
                            rv[kobj] = values[i][kobj];
                        }
                    }
                }
            } else {
                for (kobj in values[i]) {
                    if(values[i].hasOwnProperty(kobj)) {
                        if (isArray(values[i][kobj])) { 
                            sal = values[i][kobj][0];
                            count = values[i][kobj][1];
                            if ( rv.hasOwnProperty(kobj) && isArray(rv[kobj])) {
                                rv[kobj][0] += sal; 
                                rv[kobj][1] += count; 
                            } else { 
                                rv[kobj] = [sal,count]; 
                            }
                        }
                    }
                }
            }
        }
    } else {
        var t;
        for (i = 0, l = values.length; i<l ; i++) {
            switch (values[i][0]) {
                case "title" :
                    rv[values[i][1]] = null;
                    t = i;
                    break;
                case "salary":
                    rv[values[t][1]] = [values[i][1], 1];
                    break;
                default:
                    rv[values[t][1]] = null;
                    break;
            }
        }
    }
    return rv;
}

削減された値は次のとおりです: http://i.imgur.com/WbmxL.png

rereduce ステップが適用された場合の値は次のとおりです。

{Senior Engineer: [417153, 6], Engineer: [171293, 3], Assistant Engineer: [66313, 1], Senior Staff: [248397, 3], Technique Leader: [134222, 2], Staff: [72527, 1]}

私が困惑するのは、ビューが作成されるたびに、再還元された値が常に変化することです! 関数の最後にコメント (//) を追加しただけなのに。また、生成される値は常に間違っています。ビューが再作成された後の値は次のとおりです。

{Senior Engineer: [540708, 7], Senior Staff: [179364, 2], Engineer: [488026, 6], Staff: [174196, 3], Assistant Engineer: [66313, 1], Technique Leader: [120310, 2]}

私は本当に混乱しており、CouchDB でデバッグを行い、MapReduce 関数の実行を追跡する方法がわからないため、ほとんど盲目です。javascript / MapReduce の専門家が、何が問題なのかを指摘してくれませんか?

これが私の給与と肩書きの文書です。それぞれに、HTTP BULK API https://docs.google.com/open?id=0B2o1vMJ7XFKydUxGR3R3NU9QOEEを使用して CouchDB に挿入する準備が整った 1000 個のドキュメントが含まれています。

4

1 に答える 1

1

隣接するレコードが存在することに依存しています。Couch が reduce 関数に渡す一連の値をどのように分割するかは予測できません。同じ従業員の役職給与レコードの で分割が発生すると、あなたは絶対に呼び出されます。つまり、reduce 関数の特定の呼び出しでは、役職はあるが給与はない、またはその逆です。

現在のデータ構造であなたがしようとしていることを行う方法はないと思います。クライアント側で平均計算を行うか、給与と役職の両方を同じドキュメントに格納するようにドキュメント構造を変更する必要があります (後者が私のアプローチです)。

于 2012-06-27T22:33:45.087 に答える