如何合并对象从降低属性CouchDB中以rereduce功能(How to merge object

2019-07-30 03:31发布

这是我的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]);
        }
    }
}

这里所产生的键值对emited:

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

现在,我想把它降低到单个键 - 值对,与输出的值被设置成这样的JavaScript对象

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

这是我计划如何做到这一点:首先,在减少一步,我就是合并来自同一EMP_NO性能要返回的对象。 然后,在减少一步,我要创建一个具有属性名称之前基于降低值的新对象。

这很难解释,所以这里是我的减少功能:

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

但是,当我设置分组值在蒲团“无”,这不是我想要的:

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

可能有人帮我解决了这个?

Answer 1:

你推的CouchDB非常接近这里了极限 - 用减少功能来执行连接和一切。

你的问题来自于事实,CouchDB的可申请零,一个或多个rereduce步骤,但你的代码假设只有一个rereduce一步将被执行。 我怀疑null你得到来自最终rereduce一步被应用到来自rereduce一步一些结果来自减少的步骤和一些结果的事实结果。

这里有一个小图。 M是地图步骤,R是一个减少步骤,RR是rereduce步骤。

[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降低的观点,重要的是你减少步骤输出的数据具有相同的格式由您rereduce步骤输出的数据。 具体而言,这意味着,而不是存储平均数,你需要存储(求和,计数)对。



Answer 2:

它将使你的生活轻松了许多,如果你可以把职位和薪水同一名员工一份文件上。

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

那么你可以很容易地emit(doc.title, doc.salary)与内置_stats减少功能和拿不到工资统计数据为每个标题的视图。



文章来源: How to merge objects attributes from reduce to rereduce function in CouchDB