1

これは私のJSONスキーマです:

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

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

私がやりたかったのは、アクティブな各タイトルの平均給与を見つけることです。アクティブなタイトルは、「from_date」属性が「9999-01-01」に設定されたドキュメントです。

これが私のマップ関数です

function(doc) {
if (doc.type == 'salaries') {
        var dateSalaries = null;
        dateSalaries = doc.to_date.split("-");
        if(dateSalaries[0].localeCompare("9999") == 0){
            emit(doc.emp_no, ["salary", doc.salary] );
        }
    } else if (doc.type == 'titles') {
        var dateTitles = null;
        dateTitles = doc.to_date.split("-");
        if(dateTitles[0].localeCompare("9999") == 0){
            emit(doc.emp_no, ["title", doc.title]);
        }
    }
}

放出された結果のキーと値のペアは次のとおりです。

http://i.imgur.com/o1Qxz.png

今、私はそれを単一のキーと値のペアに減らしたいと思います、出力された値はこのようにjavascriptオブジェクトに設定されます

{
    "engineer" : 64342,
    "senior engineer" : 123111,
    "staff" : ...,
    "senior staf" : ...,
    .
    .
    .
}

これが私がそれを行うことを計画した方法です:最初に、reduceステップで、同じemp_noからのプロパティをマージするオブジェクトを返します。次に、reduceステップで、前にreduced値に基づいたプロパティ名を持つ新しいオブジェクトを作成します。

説明するのは難しいので、ここに私のreduce関数があります:

function(keys, values, rereduce) {
    var i, l, attr, sal, rv = {};
    if (rereduce) {
        for (i = 0, l = values.length; i<l ; ++i) {
            if (values[i].hasOwnProperty('salary')) {
                attr = values[i].title;
                sal = values[i].salary;
                if (rv[attr] instanceof Array) {
                    rv[attr].push(sal);
                } else{
                    rv[attr] = [];
                    rv[attr].push(sal);
                }
            }           
        }

        for (var x in rv) {
            if (rv.hasOwnProperty(x)) {
                var totalSalary = 0;
                for (i = 0, l = values.length; i<l ; i++) {
                    totalSalary += rv[x][i];
                }
                rv[x] = totalSalary / rv[x].length;
            }
        }

    } else {
        for (i = 0, l = values.length; i<l ; i++) {
            switch (values[i][0]) {
                case "title" : rv["title"] = values[i][1]; break;
                case "salary": rv["salary"] = values[i][1]; break;
            }
        }
    }
    return rv;
}

ここでの結果の値は、私が期待したものである減少した値です:http: //i.imgur.com/SnlOU.png

しかし、布団でグループ化の値を「none」に設定すると、それは私が望んでいたものではありません。

{Senior Engineer: null, Assistant Engineer: null, Technique Leader: null}

誰かが私がこれを解決するのを手伝ってもらえますか?

4

2 に答える 2

2

ここでは、CouchDBを限界にかなり近づけています—reduce関数を使用して結合などを実行します。

問題は、CouchDBがゼロ、1つ、または複数のrereduceステップを適用する可能性があるという事実に起因しますが、コードは、正確に1つのrereduceステップが実行されることを前提としています。あなたが得る結果は、最後のrereducenullステップがreduceステップからのいくつかの結果とrereduceステップからのいくつかの結果に適用されるという事実から来ていると思います。

これが小さな図です。Mはマップステップ、Rはリデュースステップ、RRはリリデュースステップです。

[X] [X] [X] [X] [X] [X] [X] [X] [X] [X] 
 |   |   |   |   |   |   |   |   |   | 
(M) (M) (M) (M) (M) (M) (M) (M) (M) (M)
 |   |   |   |   |   |   |   |   |   | 
(==R==) (==R==) (==R==) (==R==) (==R==)
   |       |       |       |       | 
  (== R R ==)     (== R R ==)      | 
       |               |           | 
      (====== R R ======)          | 
               |                   | 
              (======== R R ========)
                         |
                         v
                        [X]

CouchDBのreduceビューでは、reduceステップによって出力されるデータがrereduceステップによって出力されるデータと同じ形式であることが不可欠です。特に、これは、平均を保存する代わりに、(合計、カウント)ペアを保存する必要があることを意味します。

于 2012-06-26T14:14:10.220 に答える
0

同じ従業員のドキュメントに役職と給与をまとめることができれば、あなたの生活はずっと楽になります。

{
"name" : "Joe",
"title" : "Plumber",
"salary" : 60000
}

emit(doc.title, doc.salary)次に、組み込みの_statsreduce機能を使用して簡単に、各タイトルの給与統計を表示できます。

于 2012-06-27T00:25:25.487 に答える