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]}

让我疑惑的是,每次创建视图时,rereduce 的值总是在变化!即使我只是在函数末尾添加了注释(//)。此外,生成的值总是错误的。这是重新创建视图后的值:

{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专家可以帮我指出问题所在吗?

这是我的工资和头衔文件。每个包含 1000 个文档,可以使用 HTTP BULK API https://docs.google.com/open?id=0B2o1vMJ7XFKydUxGR3R3NU9QOEE插入 CouchDB

4

1 回答 1

1

您依赖于存在的相邻记录。您无法预测 Couch 将如何拆分它传递给您的 reduce 函数的一组值。您绝对会因同一员工的头衔薪水记录之间发生拆分而被调用。 这意味着在您的 reduce 函数的给定调用中,您将有一个头衔,但没有薪水,反之亦然。

我认为没有任何方法可以使用您当前的数据结构来做您想做的事情。您应该在客户端进行平均计算,或者更改文档结构,以便将薪水和职位都存储在同一个文档中(后者是我的方法)。

于 2012-06-27T22:33:45.087 回答